/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors. * Author: Seth Hillbrand * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef PCBNEW_IMPORTERS_IMPORT_FABMASTER_H_ #define PCBNEW_IMPORTERS_IMPORT_FABMASTER_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum PCB_LAYER_ID : int; class BOARD; class PROGRESS_REPORTER; class FABMASTER { public: using single_row = std::vector; FABMASTER() : has_pads( false ), has_comps( false ), has_graphic( false ), has_nets( false ), has_pins( false ), m_progressReporter( nullptr ), m_doneCount( 0 ), m_lastProgressCount( 0 ), m_totalCount( 0 ) {} bool Read( const std::string& aFile ); bool Process(); bool LoadBoard( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter ); private: wxFileName m_filename; 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 }; std::deque rows; bool has_pads; bool has_comps; bool has_graphic; bool has_nets; bool has_pins; struct FM_PAD { std::string name; bool fixed; bool via; PAD_SHAPE shape; std::string custom_name; bool top; bool bottom; bool paste; bool mask; bool drill; bool plated; bool is_octogon; int drill_size_x; int drill_size_y; int width; int height; int mask_width; int mask_height; int paste_width; int paste_height; int x_offset; int y_offset; int antipad_size; struct HASH { std::size_t operator()( const FM_PAD& aPad ) const { return std::hash{}( aPad.name ); } }; }; std::unordered_map pads; enum COMPCLASS { COMPCLASS_NONE, COMPCLASS_IO, COMPCLASS_IC, COMPCLASS_DISCRETE }; enum SYMTYPE { SYMTYPE_NONE, SYMTYPE_PACKAGE, SYMTYPE_MECH, SYMTYPE_FORMAT, SYMTYPE_DRAFTING }; // A!NET_NAME!REFDES!PIN_NUMBER!PIN_NAME!PIN_GROUND!PIN_POWER! struct NETNAME { std::string name; ///!< NET_NAME std::string refdes; ///!< REFDES std::string pin_num; ///!< PIN_NUMBER std::string pin_name; ///!< PIN_NAME bool pin_gnd; ///!< PIN_GND bool pin_pwr; ///!< PIN_PWR struct LESS { bool operator()(const NETNAME& lhs, const NETNAME& rhs) const { if( lhs.refdes == rhs.refdes ) return lhs.pin_num < rhs.pin_num; return lhs.refdes < rhs.refdes; } }; }; std::map, NETNAME> pin_nets; std::set netnames; struct CLASS { std::string name; ///!< CLASS std::string subclass; ///!< SUBCLASS }; enum GRAPHIC_SHAPE { 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 }; enum GRAPHIC_TYPE { GR_TYPE_NONE, GR_TYPE_CONNECT, GR_TYPE_NOTCONNECT, GR_TYPE_SHAPE, GR_TYPE_POLYGON, GR_TYPE_VOID }; struct GRAPHIC_ITEM { int start_x; ///& lhs, const std::unique_ptr& rhs) const { if( lhs->refdes != rhs->refdes ) return lhs->refdes < rhs->refdes; if( lhs->layer != rhs->layer ) return lhs->layer < rhs->layer; return lhs->seq < rhs->seq; } }; }; struct GRAPHIC_LINE : public GRAPHIC_ITEM { int end_x; ///, GRAPHIC_ITEM::SEQ_CMP>; /// 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! struct FABMASTER_LAYER { int id; ///id < rhs->id; } }; }; std::map layers; /** * 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! */ struct FABMASTER_PAD_SHAPE { std::string name; /// elements; struct HASH { std::size_t operator()( const std::unique_ptr& aPad ) const { return std::hash{}( aPad->name ); } }; }; std::unordered_map pad_shapes; // * A!SYM_TYPE!SYM_NAME!REFDES!SYM_X!SYM_Y!SYM_ROTATE!SYM_MIRROR!NET_NAME!CLASS!SUBCLASS!RECORD_TAG! // * GRAPHIC_DATA_NAME!GRAPHIC_DATA_NUMBER!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!GRAPHIC_DATA_10!COMP_DEVICE_TYPE! // * COMP_PACKAGE!COMP_PART_NUMBER!COMP_VALUE!CLIP_DRAWING! struct SYMBOL { int sym_id; /// elements; struct HASH { std::size_t operator()( const FABMASTER::SYMBOL& aSym ) const { return std::hash{}( aSym.name ); } }; }; // Temporary data structure to pass graphic data from file for processing struct GRAPHIC_DATA { std::string graphic_dataname; std::string graphic_datanum; std::string graphic_data1; std::string graphic_data2; std::string graphic_data3; std::string graphic_data4; std::string graphic_data5; std::string graphic_data6; std::string graphic_data7; std::string graphic_data8; std::string graphic_data9; std::string graphic_data10; }; std::unordered_map symbols; // * 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! struct GEOM_GRAPHIC { std::string subclass; /// elements; struct BY_ID { bool operator()(const GEOM_GRAPHIC& lhs, const GEOM_GRAPHIC& rhs) const { return lhs.id < rhs.id; } }; }; std::vector board_graphics; std::map> comp_graphics; // A!VIA_X!VIA_Y!PAD_STACK_NAME!NET_NAME!TEST_POINT! struct FM_VIA { int x; ///> vias; // 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! struct TRACE { std::string lclass; ///& lhs, const std::unique_ptr& rhs) const { return lhs->id < rhs->id; } }; }; std::set, TRACE::BY_ID> traces; std::set, TRACE::BY_ID> zones; std::set, TRACE::BY_ID> polygons; std::set, TRACE::BY_ID> refdes; // 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! struct COMPONENT { std::string refdes; ///{}( aCmp.refdes ); } }; }; std::map>> components; // A!SYM_NAME!SYM_MIRROR!PIN_NAME!PIN_NUMBER!PIN_X!PIN_Y!PAD_STACK_NAME!REFDES!PIN_ROTATION!TEST_POINT! struct PIN { std::string name; ///& lhs, const std::unique_ptr& rhs) const { return lhs->pin_number < rhs->pin_number; } }; }; std::map, PIN::BY_NUM>> pins; std::map layer_map; 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 ); /** * Processes data from text vectors into internal database * for further ordering * @param aRow vector offset being processed * @return Count of the number of rows processed, return -1 on error */ double processScaleFactor( size_t aRow ); size_t processPadStacks( size_t aRow ); size_t processCustomPads( size_t aRow ); size_t processGeometry( size_t aRow ); size_t processVias( size_t aRow ); size_t processTraces( size_t aRow ); size_t processFootprints( size_t aRow ); size_t processNets( size_t aRow ); size_t processLayers( size_t aRow ); size_t processSimpleLayers( size_t aRow ); size_t processPadStackLayers( size_t aRow ); size_t processSymbols( size_t aRow ); size_t processPins( size_t aRow ); /** * Specialty functions for processing graphical data rows into the internal * database * @param aData Loaded data vector * @param aScale Prior loaded scale factor * @return Pointer to newly allocated graphical item or nullptr on failure */ GRAPHIC_ITEM* processGraphic( const GRAPHIC_DATA& aData, double aScale ); GRAPHIC_ARC* processArc( const GRAPHIC_DATA& aData, double aScale ); GRAPHIC_LINE* processLine( const GRAPHIC_DATA& aData, double aScale ); GRAPHIC_TEXT* processText( const GRAPHIC_DATA& aData, double aScale ); GRAPHIC_RECTANGLE* processRectangle( const GRAPHIC_DATA& aData, double aScale ); PCB_LAYER_ID getLayer( const std::string& aLayerName ); bool assignLayers(); /** * Reads the double/integer value from a std string independent of the user locale * @param aStr string to generate value from * @return 0 if value cannot be created */ double readDouble( const std::string& aStr ) const; int readInt( const std::string& aStr ) const; /** * Sets zone priorities based on zone BB size. Larger bounding boxes get smaller priorities * so smaller zones can knock out areas where they overlap. * @param aBoard * @return True if successful */ bool orderZones( BOARD* aBoard ); /** * Loads sections of the database into the board * @param aBoard * @return True if successful */ bool loadZones( BOARD* aBoard ); bool loadOutline( BOARD* aBoard, const std::unique_ptr& 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& aLine); bool loadZone( BOARD* aBoard, const std::unique_ptr& aLine); bool loadPolygon( BOARD* aBoard, const std::unique_ptr& aLine); bool loadFootprints( BOARD* aBoard ); SHAPE_POLY_SET loadShapePolySet( const graphic_element& aLine); PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr unsigned m_doneCount; unsigned m_lastProgressCount; unsigned m_totalCount; ///< for progress reporting }; #endif /* PCBNEW_IMPORTERS_IMPORT_FABMASTER_H_ */