KiCad PCB EDA Suite
DSN::SPECCTRA_DB Class Reference

A DSN data tree, usually coming from a DSN file. More...

#include <specctra.h>

Inheritance diagram for DSN::SPECCTRA_DB:

Public Member Functions

 SPECCTRA_DB ()
 
virtual ~SPECCTRA_DB ()
 
void SetPCB (PCB *aPcb)
 Delete any existing PCB and replaces it with the given one. More...
 
PCBGetPCB ()
 
void SetSESSION (SESSION *aSession)
 Delete any existing SESSION and replaces it with the given one. More...
 
SESSIONGetSESSION ()
 
void LoadPCB (const wxString &aFilename)
 A recursive descent parser for a SPECCTRA DSN "design" file. More...
 
void LoadSESSION (const wxString &aFilename)
 A recursive descent parser for a SPECCTRA DSN "session" file. More...
 
void ExportPCB (const wxString &aFilename, bool aNameChange=false)
 Write the internal PCB instance out as a SPECTRA DSN format file. More...
 
void FromBOARD (BOARD *aBoard)
 Add the entire BOARD to the PCB but does not write it out. More...
 
void FromSESSION (BOARD *aBoard)
 Add the entire #SESSION info to a BOARD but does not write it out. More...
 
void ExportSESSION (const wxString &aFilename)
 Write the internal #SESSION instance out as a #SPECTRA DSN format file. More...
 
bool BuiltBoardOutlines (BOARD *aBoard)
 Build the board outlines and store it in m_brd_outlines. More...
 
void FlipFOOTPRINTs (BOARD *aBoard)
 Flip the footprints which are on the back side of the board to the front. More...
 
void RevertFOOTPRINTs (BOARD *aBoard)
 Flip the footprints which were on the back side of the board back to the back. More...
 

Static Public Member Functions

static PCBMakePCB ()
 Make a PCB with all the default ELEMs and parts on the heap. More...
 

Private Member Functions

void buildLayerMaps (BOARD *aBoard)
 Create a few data translation structures for layer name and number mapping between the DSN::PCB structure and the KiCad BOARD structure. More...
 
int findLayerName (const std::string &aLayerName) const
 Return the PCB layer index for a given layer name, within the specctra sessionfile. More...
 
void readCOMPnPIN (std::string *component_id, std::string *pid_id)
 Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen. More...
 
void readTIME (time_t *time_stamp)
 Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year". More...
 
void doPCB (PCB *growth)
 
void doPARSER (PARSER *growth)
 
void doRESOLUTION (UNIT_RES *growth)
 
void doUNIT (UNIT_RES *growth)
 
void doSTRUCTURE (STRUCTURE *growth)
 
void doSTRUCTURE_OUT (STRUCTURE_OUT *growth)
 
void doLAYER_NOISE_WEIGHT (LAYER_NOISE_WEIGHT *growth)
 
void doSPECCTRA_LAYER_PAIR (SPECCTRA_LAYER_PAIR *growth)
 
void doBOUNDARY (BOUNDARY *growth)
 
void doRECTANGLE (RECTANGLE *growth)
 
void doPATH (PATH *growth)
 
void doSTRINGPROP (STRINGPROP *growth)
 
void doTOKPROP (TOKPROP *growth)
 
void doVIA (VIA *growth)
 
void doCONTROL (CONTROL *growth)
 
void doLAYER (LAYER *growth)
 
void doRULE (RULE *growth)
 
void doKEEPOUT (KEEPOUT *growth)
 
void doCIRCLE (CIRCLE *growth)
 
void doQARC (QARC *growth)
 
void doWINDOW (WINDOW *growth)
 
void doCONNECT (CONNECT *growth)
 
void doREGION (REGION *growth)
 
void doCLASS_CLASS (CLASS_CLASS *growth)
 
void doLAYER_RULE (LAYER_RULE *growth)
 
void doCLASSES (CLASSES *growth)
 
void doGRID (GRID *growth)
 
void doPLACE (PLACE *growth)
 
void doCOMPONENT (COMPONENT *growth)
 
void doPLACEMENT (PLACEMENT *growth)
 
void doPROPERTIES (PROPERTIES *growth)
 
void doPADSTACK (PADSTACK *growth)
 
void doSHAPE (SHAPE *growth)
 
void doIMAGE (IMAGE *growth)
 
void doLIBRARY (LIBRARY *growth)
 
void doPIN (PIN *growth)
 
void doNET (NET *growth)
 
void doNETWORK (NETWORK *growth)
 
void doCLASS (CLASS *growth)
 
void doTOPOLOGY (TOPOLOGY *growth)
 
void doFROMTO (FROMTO *growth)
 
void doCOMP_ORDER (COMP_ORDER *growth)
 
void doWIRE (WIRE *growth)
 
void doWIRE_VIA (WIRE_VIA *growth)
 
void doWIRING (WIRING *growth)
 
void doSESSION (SESSION *growth)
 
void doANCESTOR (ANCESTOR *growth)
 
void doHISTORY (HISTORY *growth)
 
void doROUTE (ROUTE *growth)
 
void doWAS_IS (WAS_IS *growth)
 
void doNET_OUT (NET_OUT *growth)
 
void doSUPPLY_PIN (SUPPLY_PIN *growth)
 
void fillBOUNDARY (BOARD *aBoard, BOUNDARY *aBoundary)
 Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tree. More...
 
IMAGEmakeIMAGE (BOARD *aBoard, FOOTPRINT *aFootprint)
 Allocates an I::MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT. More...
 
PADSTACKmakePADSTACK (BOARD *aBoard, PAD *aPad)
 Create a #PADSTACK which matches the given pad. More...
 
PADSTACKmakeVia (int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
 Make a round through hole #PADSTACK using the given KiCad diameter in deci-mils. More...
 
PADSTACKmakeVia (const ::PCB_VIA *aVia)
 Make any kind of #PADSTACK using the given KiCad #VIA. More...
 
void deleteNETs ()
 Delete all the NETs that may be in here. More...
 
void exportNETCLASS (const std::shared_ptr< NETCLASS > &aNetClass, BOARD *aBoard)
 Export aNetClass to the DSN file. More...
 
PCB_TRACKmakeTRACK (WIRE *wire, PATH *aPath, int aPointIndex, int aNetcode)
 Create a #TRACK form the #PATH and BOARD info. More...
 
PCB_VIAmakeVIA (WIRE_VIA *aVia, PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
 Instantiate a KiCad #VIA on the heap and initializes it with internal values consistent with the given #PADSTACK, #POINT, and netcode. More...
 

Private Attributes

PCBm_pcb
 
SHAPE_POLY_SET m_brd_outlines
 
SESSIONm_session
 
wxString m_filename
 
std::string m_quote_char
 
bool m_footprintsAreFlipped
 
STRING_FORMATTER m_sf
 
STRINGS m_layerIds
 indexed by PCB layer number More...
 
std::vector< int > m_kicadLayer2pcb
 maps BOARD layer number to PCB layer numbers More...
 
std::vector< PCB_LAYER_IDm_pcbLayer2kicad
 maps PCB layer number to BOARD layer numbers More...
 
UNIT_RESm_routeResolution
 used during FromSESSION() only, memory for it is not owned here. More...
 
BOARDm_sessionBoard
 a copy to avoid passing as an argument, memory for it is not owned here. More...
 
PADSTACKSET m_padstackset
 
std::vector< NET * > m_nets
 we don't want ownership here permanently, so we don't use boost::ptr_vector More...
 
int m_top_via_layer
 specctra cu layers, 0 based index: More...
 
int m_bot_via_layer
 

Static Private Attributes

static const KEYWORD keywords []
 specctra DSN keywords More...
 
static const KICAD_T scanPADs []
 

Detailed Description

A DSN data tree, usually coming from a DSN file.

Is essentially a SPECCTRA_PARSER class.

Definition at line 3647 of file specctra.h.

Constructor & Destructor Documentation

◆ SPECCTRA_DB()

DSN::SPECCTRA_DB::SPECCTRA_DB ( )
inline

Definition at line 3651 of file specctra.h.

3651 :
3652 SPECCTRA_LEXER( 0 ) // LINE_READER* == nullptr, no DSNLEXER::PushReader()
3653 {
3654 // The LINE_READER will be pushed from an automatic instantiation,
3655 // we don't own it:
3656 wxASSERT( !iOwnReaders );
3657
3658 m_pcb = 0;
3659 m_session = 0;
3660 m_quote_char += '"';
3661 m_footprintsAreFlipped = false;
3662
3663 SetSpecctraMode( true );
3664
3665 // Avoid not initialized members:
3666 m_routeResolution = nullptr;
3667 m_sessionBoard = nullptr;
3668 m_top_via_layer = 0;
3669 m_bot_via_layer = 0;
3670 }
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:4008
UNIT_RES * m_routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3995
BOARD * m_sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3998
bool m_footprintsAreFlipped
Definition: specctra.h:3985
SESSION * m_session
Definition: specctra.h:3981
std::string m_quote_char
Definition: specctra.h:3983

References m_bot_via_layer, m_footprintsAreFlipped, m_pcb, m_quote_char, m_routeResolution, m_session, m_sessionBoard, and m_top_via_layer.

◆ ~SPECCTRA_DB()

virtual DSN::SPECCTRA_DB::~SPECCTRA_DB ( )
inlinevirtual

Definition at line 3672 of file specctra.h.

3673 {
3674 delete m_pcb;
3675 delete m_session;
3676
3677 deleteNETs();
3678 }
void deleteNETs()
Delete all the NETs that may be in here.
Definition: specctra.h:3945

References deleteNETs(), m_pcb, and m_session.

Member Function Documentation

◆ buildLayerMaps()

void DSN::SPECCTRA_DB::buildLayerMaps ( BOARD aBoard)
private

Create a few data translation structures for layer name and number mapping between the DSN::PCB structure and the KiCad BOARD structure.

Parameters
aBoardThe BOARD to create the maps for.

Definition at line 76 of file specctra.cpp.

77{
78 // specctra wants top physical layer first, then going down to the
79 // bottom most physical layer in physical sequence.
80 // Same as KiCad now except for B_Cu
81 unsigned layerCount = aBoard->GetCopperLayerCount();
82
83 m_layerIds.clear();
84 m_pcbLayer2kicad.resize( layerCount );
85 m_kicadLayer2pcb.resize( B_Cu + 1 );
86
87#if 0 // was:
88 for( int kiNdx = layerCount - 1, pcbNdx=FIRST_LAYER; kiNdx >= 0; --kiNdx, ++pcbNdx )
89 {
90 int kilayer = (kiNdx>0 && kiNdx==layerCount-1) ? F_Cu : kiNdx;
91
92 // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
93 pcbLayer2kicad[pcbNdx] = kilayer;
94 kicadLayer2pcb[kilayer] = pcbNdx;
95
96 // save the specctra layer name in SPECCTRA_DB::layerIds for later.
97 layerIds.push_back( TO_UTF8( aBoard->GetLayerName( ToLAYER_ID( kilayer ) ) ) );
98 }
99#else
100
101 // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
102
103 for( unsigned i = 0; i < m_kicadLayer2pcb.size(); ++i )
104 {
105 if( i < layerCount-1 )
106 m_kicadLayer2pcb[i] = i;
107 else
108 m_kicadLayer2pcb[i] = layerCount - 1;
109 }
110
111 for( unsigned i = 0; i < m_pcbLayer2kicad.size(); ++i )
112 {
113 PCB_LAYER_ID id = ( i < layerCount-1 ) ? ToLAYER_ID( i ) : B_Cu;
114
115 m_pcbLayer2kicad[i] = id;
116
117 // save the specctra layer name in SPECCTRA_DB::layerIds for later.
118 m_layerIds.push_back(TO_UTF8( aBoard->GetLayerName( id ) ) );
119 }
120
121#endif
122}
int GetCopperLayerCount() const
Definition: board.cpp:473
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:384
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3989
std::vector< PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3992
std::vector< int > m_kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
Definition: specctra.h:3991
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ B_Cu
Definition: layer_ids.h:95
@ F_Cu
Definition: layer_ids.h:64
#define FIRST_LAYER
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:926
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96

References B_Cu, F_Cu, FIRST_LAYER, BOARD::GetCopperLayerCount(), BOARD::GetLayerName(), m_kicadLayer2pcb, m_layerIds, m_pcbLayer2kicad, TO_UTF8, and ToLAYER_ID().

Referenced by FromBOARD(), and FromSESSION().

◆ BuiltBoardOutlines()

bool DSN::SPECCTRA_DB::BuiltBoardOutlines ( BOARD aBoard)

Build the board outlines and store it in m_brd_outlines.

Because it calls GetBoardPolygonOutlines() it must be called before flipping footprints

Returns
false if the board outlines cannot be built (not closed outlines)

Definition at line 232 of file specctra_export.cpp.

233{
234 return aBoard->GetBoardPolygonOutlines( m_brd_outlines );
235}
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1883
SHAPE_POLY_SET m_brd_outlines
Definition: specctra.h:3980

References BOARD::GetBoardPolygonOutlines(), and m_brd_outlines.

Referenced by ExportBoardToSpecctraFile().

◆ deleteNETs()

void DSN::SPECCTRA_DB::deleteNETs ( )
inlineprivate

Delete all the NETs that may be in here.

Definition at line 3945 of file specctra.h.

3946 {
3947 for( unsigned n = 0; n < m_nets.size(); ++n )
3948 delete m_nets[n];
3949
3950 m_nets.clear();
3951 }
std::vector< NET * > m_nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
Definition: specctra.h:4005

References m_nets.

Referenced by FromBOARD(), and ~SPECCTRA_DB().

◆ doANCESTOR()

void DSN::SPECCTRA_DB::doANCESTOR ( ANCESTOR growth)
private

Definition at line 3275 of file specctra.cpp.

3276{
3277 T tok;
3278
3279 /* <ancestor_file_descriptor >::=
3280 (ancestor <file_path_name> (created_time <time_stamp> )
3281 [(comment <comment_string> )])
3282 */
3283
3284 NeedSYMBOL();
3285 growth->filename = CurText();
3286
3287 while( ( tok = NextTok() ) != T_RIGHT )
3288 {
3289 if( tok != T_LEFT )
3290 Expecting( T_LEFT );
3291
3292 tok = NextTok();
3293
3294 switch( tok )
3295 {
3296 case T_created_time:
3297 readTIME( &growth->time_stamp );
3298 NeedRIGHT();
3299 break;
3300
3301 case T_comment:
3302 NeedSYMBOL();
3303 growth->comment = CurText();
3304 NeedRIGHT();
3305 break;
3306
3307 default:
3308 Unexpected( CurText() );
3309 }
3310 }
3311}
void readTIME(time_t *time_stamp)
Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year".
Definition: specctra.cpp:179

References DSN::ANCESTOR::comment, DSN::ANCESTOR::filename, readTIME(), and DSN::ANCESTOR::time_stamp.

Referenced by doHISTORY().

◆ doBOUNDARY()

void DSN::SPECCTRA_DB::doBOUNDARY ( BOUNDARY growth)
private

Definition at line 1036 of file specctra.cpp.

1037{
1038 T tok = NextTok();
1039
1040 if( tok != T_LEFT )
1041 Expecting( T_LEFT );
1042
1043 tok = NextTok();
1044
1045 if( tok == T_rect )
1046 {
1047 if( growth->paths.size() )
1048 Unexpected( "rect when path already encountered" );
1049
1050 growth->rectangle = new RECTANGLE( growth );
1051 doRECTANGLE( growth->rectangle );
1052 NeedRIGHT();
1053 }
1054 else if( tok == T_path )
1055 {
1056 if( growth->rectangle )
1057 Unexpected( "path when rect already encountered" );
1058
1059 for(;;)
1060 {
1061 if( tok != T_path )
1062 Expecting( T_path );
1063
1064 PATH* path = new PATH( growth, T_path );
1065 growth->paths.push_back( path );
1066
1067 doPATH( path );
1068
1069 tok = NextTok();
1070 if( tok == T_RIGHT )
1071 break;
1072
1073 if( tok != T_LEFT )
1074 Expecting(T_LEFT);
1075
1076 tok = NextTok();
1077 }
1078 }
1079 else
1080 {
1081 Expecting( "rect|path" );
1082 }
1083}
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137
void doPATH(PATH *growth)
Definition: specctra.cpp:1086

References doPATH(), doRECTANGLE(), path, DSN::BOUNDARY::paths, RECTANGLE, and DSN::BOUNDARY::rectangle.

Referenced by doSTRUCTURE().

◆ doCIRCLE()

void DSN::SPECCTRA_DB::doCIRCLE ( CIRCLE growth)
private

Definition at line 1166 of file specctra.cpp.

1167{
1168 T tok;
1169
1170 NeedSYMBOLorNUMBER();
1171 growth->layer_id = CurText();
1172
1173 if( NextTok() != T_NUMBER )
1174 Expecting( T_NUMBER );
1175
1176 growth->diameter = strtod( CurText(), 0 );
1177
1178 tok = NextTok();
1179
1180 if( tok == T_NUMBER )
1181 {
1182 growth->vertex.x = strtod( CurText(), 0 );
1183
1184 if( NextTok() != T_NUMBER )
1185 Expecting( T_NUMBER );
1186
1187 growth->vertex.y = strtod( CurText(), 0 );
1188
1189 tok = NextTok();
1190 }
1191
1192 if( tok != T_RIGHT )
1193 Expecting( T_RIGHT );
1194}

References DSN::CIRCLE::diameter, DSN::CIRCLE::layer_id, DSN::CIRCLE::vertex, DSN::POINT::x, and DSN::POINT::y.

Referenced by doKEEPOUT(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doCLASS()

void DSN::SPECCTRA_DB::doCLASS ( CLASS growth)
private

Definition at line 2697 of file specctra.cpp.

2698{
2699 T tok;
2700
2701 /* <class_descriptor >::=
2702 (class
2703 <class_id > {[{<net_id >} | {<composite_name_list> }]}
2704 [<circuit_descriptor> ]
2705 [<rule_descriptor> ]
2706 [{<layer_rule_descriptor> }]
2707 [<topology_descriptor> ]
2708 )
2709 */
2710
2711 NeedSYMBOL();
2712
2713 growth->class_id = CurText();
2714
2715 // do net_ids, do not support <composite_name_list>s at this time
2716 while( IsSymbol( tok = NextTok() ) )
2717 {
2718 growth->net_ids.push_back( CurText() );
2719 }
2720
2721
2722 while( tok != T_RIGHT )
2723 {
2724 if( tok != T_LEFT )
2725 Expecting( T_LEFT );
2726
2727 tok = NextTok();
2728
2729 switch( tok )
2730 {
2731 case T_rule:
2732 if( growth->rules )
2733 Unexpected( tok );
2734
2735 growth->rules = new RULE( growth, T_rule );
2736 doRULE( growth->rules );
2737 break;
2738
2739 case T_layer_rule:
2740 LAYER_RULE* layer_rule;
2741 layer_rule = new LAYER_RULE( growth );
2742 growth->layer_rules.push_back( layer_rule );
2743 doLAYER_RULE( layer_rule );
2744 break;
2745
2746 case T_topology:
2747 if( growth->topology )
2748 Unexpected( tok );
2749
2750 growth->topology = new TOPOLOGY( growth );
2751 doTOPOLOGY( growth->topology );
2752 break;
2753
2754 case T_circuit: // handle all the circuit_descriptor here as strings
2755 {
2756 std::string builder;
2757 int bracketNesting = 1; // we already saw the opening T_LEFT
2758 tok = T_NONE;
2759
2760 while( bracketNesting != 0 && tok != T_EOF )
2761 {
2762 tok = NextTok();
2763
2764 if( tok == T_LEFT )
2765 ++bracketNesting;
2766 else if( tok == T_RIGHT )
2767 --bracketNesting;
2768
2769 if( bracketNesting >= 1 )
2770 {
2771 T previousTok = (T) PrevTok();
2772
2773 if( previousTok != T_LEFT && previousTok != T_circuit && tok != T_RIGHT )
2774 builder += ' ';
2775
2776 if( tok == T_STRING )
2777 builder += m_quote_char;
2778
2779 builder += CurText();
2780
2781 if( tok == T_STRING )
2782 builder += m_quote_char;
2783 }
2784
2785 // When the nested rule is closed with a T_RIGHT and we are back down
2786 // to bracketNesting == 0, then save the builder and break;
2787 if( bracketNesting == 0 )
2788 {
2789 growth->circuit.push_back( builder );
2790 break;
2791 }
2792 }
2793
2794 if( tok == T_EOF )
2795 Unexpected( T_EOF );
2796
2797 break;
2798 } // scope bracket
2799
2800 default:
2801 Unexpected( CurText() );
2802 } // switch
2803
2804 tok = NextTok();
2805
2806 } // while
2807}
void doTOPOLOGY(TOPOLOGY *growth)
Definition: specctra.cpp:2658
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1851

References DSN::CLASS::circuit, DSN::CLASS::class_id, doLAYER_RULE(), doRULE(), doTOPOLOGY(), DSN::CLASS::layer_rules, m_quote_char, DSN::CLASS::net_ids, RULE, DSN::CLASS::rules, and DSN::CLASS::topology.

Referenced by doNETWORK().

◆ doCLASS_CLASS()

void DSN::SPECCTRA_DB::doCLASS_CLASS ( CLASS_CLASS growth)
private

Definition at line 1702 of file specctra.cpp.

1703{
1704 T tok = NextTok();
1705
1706 if( tok != T_LEFT )
1707 Expecting( T_LEFT );
1708
1709 while( ( tok = NextTok() ) != T_RIGHT )
1710 {
1711 switch( tok )
1712 {
1713 case T_classes:
1714 if( growth->classes )
1715 Unexpected( tok );
1716
1717 growth->classes = new CLASSES( growth );
1718 doCLASSES( growth->classes );
1719 break;
1720
1721 case T_rule:
1722 // only T_class_class takes a T_rule
1723 if( growth->Type() == T_region_class_class )
1724 Unexpected( tok );
1725
1726 RULE* rule;
1727 rule = new RULE( growth, T_rule );
1728 growth->Append( rule );
1729 doRULE( rule );
1730 break;
1731
1732 case T_layer_rule:
1733 // only T_class_class takes a T_layer_rule
1734 if( growth->Type() == T_region_class_class )
1735 Unexpected( tok );
1736
1737 LAYER_RULE* layer_rule;
1738 layer_rule = new LAYER_RULE( growth );
1739 growth->Append( layer_rule );
1740 doLAYER_RULE( layer_rule );
1741 break;
1742
1743 default:
1744 Unexpected( tok );
1745 }
1746 }
1747}
void doCLASSES(CLASSES *growth)
Definition: specctra.cpp:1750

References DSN::ELEM_HOLDER::Append(), DSN::CLASS_CLASS::classes, doCLASSES(), doLAYER_RULE(), doRULE(), RULE, and DSN::ELEM::Type().

Referenced by doREGION().

◆ doCLASSES()

void DSN::SPECCTRA_DB::doCLASSES ( CLASSES growth)
private

Definition at line 1750 of file specctra.cpp.

1751{
1752 T tok = NextTok();
1753
1754 // require at least 2 class_ids
1755
1756 if( !IsSymbol( tok ) )
1757 Expecting( "class_id" );
1758
1759 growth->class_ids.push_back( CurText() );
1760
1761 do
1762 {
1763 tok = NextTok();
1764
1765 if( !IsSymbol( tok ) )
1766 Expecting( "class_id" );
1767
1768 growth->class_ids.push_back( CurText() );
1769
1770 } while( ( tok = NextTok() ) != T_RIGHT );
1771}

References DSN::CLASSES::class_ids.

Referenced by doCLASS_CLASS().

◆ doCOMP_ORDER()

void DSN::SPECCTRA_DB::doCOMP_ORDER ( COMP_ORDER growth)
private

Definition at line 2856 of file specctra.cpp.

2857{
2858 T tok;
2859
2860 /* <component_order_descriptor >::=
2861 (comp_order {<placement_id> })
2862 */
2863
2864 while( IsSymbol( tok = NextTok() ) )
2865 {
2866 growth->placement_ids.push_back( CurText() );
2867 }
2868
2869 if( tok != T_RIGHT )
2870 Expecting( T_RIGHT );
2871}

References DSN::COMP_ORDER::placement_ids.

Referenced by doNET(), and doTOPOLOGY().

◆ doCOMPONENT()

void DSN::SPECCTRA_DB::doCOMPONENT ( COMPONENT growth)
private

Definition at line 2011 of file specctra.cpp.

2012{
2013 T tok = NextTok();
2014
2015 if( !IsSymbol( tok ) && tok != T_NUMBER )
2016 Expecting( "image_id" );
2017
2018 growth->image_id = CurText();
2019
2020 while( ( tok = NextTok() ) != T_RIGHT )
2021 {
2022 if( tok != T_LEFT )
2023 Expecting( T_LEFT );
2024
2025 tok = NextTok();
2026
2027 switch( tok )
2028 {
2029 case T_place:
2030 PLACE* place;
2031 place = new PLACE( growth );
2032 growth->places.push_back( place );
2033 doPLACE( place );
2034 break;
2035
2036 default:
2037 Unexpected( tok );
2038 }
2039 }
2040}
void doPLACE(PLACE *growth)
Definition: specctra.cpp:1876

References doPLACE(), DSN::COMPONENT::image_id, PLACE, and DSN::COMPONENT::places.

Referenced by doPLACEMENT().

◆ doCONNECT()

void DSN::SPECCTRA_DB::doCONNECT ( CONNECT growth)
private

Definition at line 942 of file specctra.cpp.

943{
944 /* from page 143 of specctra spec:
945
946 (connect
947 {(terminal <object_type> [<pin_reference> ])}
948 )
949 */
950
951 T tok = NextTok();
952
953 while( tok != T_RIGHT )
954 {
955 if( tok!=T_LEFT )
956 Expecting( T_LEFT );
957
958 tok = NextTok();
959
960 switch( tok )
961 {
962 case T_terminal:
963 // since we do not use the terminal information, simply toss it.
964 while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
965 ;
966 break;
967
968 default:
969 Unexpected( CurText() );
970 }
971
972 tok = NextTok();
973 }
974}

Referenced by doWIRE().

◆ doCONTROL()

void DSN::SPECCTRA_DB::doCONTROL ( CONTROL growth)
private

Definition at line 1276 of file specctra.cpp.

1277{
1278 T tok;
1279
1280 while( (tok = NextTok()) != T_RIGHT )
1281 {
1282 if( tok != T_LEFT )
1283 Expecting( T_LEFT );
1284
1285 tok = NextTok();
1286
1287 switch( tok )
1288 {
1289 case T_via_at_smd:
1290 tok = NextTok();
1291
1292 if( tok!=T_on && tok!=T_off )
1293 Expecting( "on|off" );
1294
1295 growth->via_at_smd = (tok==T_on);
1296 NeedRIGHT();
1297 break;
1298
1299 case T_off_grid:
1300 case T_route_to_fanout_only:
1301 case T_force_to_terminal_point:
1302 case T_same_net_checking:
1303 case T_checking_trim_by_pin:
1304 case T_noise_calculation:
1305 case T_noise_accumulation:
1306 case T_include_pins_in_crosstalk:
1307 case T_bbv_ctr2ctr:
1308 case T_average_pair_length:
1309 case T_crosstalk_model:
1310 case T_roundoff_rotation:
1311 case T_microvia:
1312 case T_reroute_order_viols:
1313 TOKPROP* tokprop;
1314 tokprop = new TOKPROP( growth, tok );
1315 growth->Append( tokprop );
1316 doTOKPROP( tokprop );
1317 break;
1318
1319 default:
1320 Unexpected( CurText() );
1321 }
1322 }
1323}
void doTOKPROP(TOKPROP *growth)
Definition: specctra.cpp:1232

References DSN::ELEM_HOLDER::Append(), doTOKPROP(), and DSN::CONTROL::via_at_smd.

Referenced by doSTRUCTURE().

◆ doFROMTO()

void DSN::SPECCTRA_DB::doFROMTO ( FROMTO growth)
private

Definition at line 2874 of file specctra.cpp.

2875{
2876 T tok;
2877
2878 /* <fromto_descriptor >::=
2879 {(fromto
2880 [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
2881 [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
2882 [(type [fix | normal | soft])]
2883 [(net <net_id >)]
2884 [<rule_descriptor> ]
2885 [<circuit_descriptor> ]
2886 [{<layer_rule_descriptor> }]
2887 )}
2888 */
2889
2890
2891 // read the first two grammar items in as 2 single tokens, i.e. do not
2892 // split apart the <pin_reference>s into 3 separate tokens. Do this by
2893 // turning off the string delimiter in the lexer.
2894
2895 char old = SetStringDelimiter( 0 );
2896
2897 if( !IsSymbol(NextTok() ) )
2898 {
2899 SetStringDelimiter( old );
2900 Expecting( T_SYMBOL );
2901 }
2902
2903 growth->fromText = CurText();
2904
2905 if( !IsSymbol(NextTok() ) )
2906 {
2907 SetStringDelimiter( old );
2908 Expecting( T_SYMBOL );
2909 }
2910
2911 growth->toText = CurText();
2912
2913 SetStringDelimiter( old );
2914
2915 while( ( tok = NextTok() ) != T_RIGHT )
2916 {
2917 if( tok != T_LEFT )
2918 Expecting( T_LEFT );
2919
2920 tok = NextTok();
2921
2922 switch( tok )
2923 {
2924 case T_type:
2925 tok = NextTok();
2926
2927 if( tok != T_fix && tok != T_normal && tok != T_soft )
2928 Expecting( "fix|normal|soft" );
2929
2930 growth->fromto_type = tok;
2931 NeedRIGHT();
2932 break;
2933
2934 case T_rule:
2935 if( growth->rules )
2936 Unexpected( tok );
2937
2938 growth->rules = new RULE( growth, T_rule );
2939 doRULE( growth->rules );
2940 break;
2941
2942 case T_layer_rule:
2943 LAYER_RULE* layer_rule;
2944 layer_rule = new LAYER_RULE( growth );
2945 growth->layer_rules.push_back( layer_rule );
2946 doLAYER_RULE( layer_rule );
2947 break;
2948
2949 case T_net:
2950 if( growth->net_id.size() )
2951 Unexpected( tok );
2952
2953 NeedSYMBOL();
2954 growth->net_id = CurText();
2955 NeedRIGHT();
2956 break;
2957
2958 // circuit descriptor not supported at this time
2959
2960 default:
2961 Unexpected( CurText() );
2962 }
2963 }
2964}

References doLAYER_RULE(), doRULE(), DSN::FROMTO::fromText, DSN::FROMTO::fromto_type, DSN::FROMTO::layer_rules, DSN::FROMTO::net_id, RULE, DSN::FROMTO::rules, and DSN::FROMTO::toText.

Referenced by doNET(), and doTOPOLOGY().

◆ doGRID()

void DSN::SPECCTRA_DB::doGRID ( GRID growth)
private

Definition at line 1774 of file specctra.cpp.

1775{
1776 T tok = NextTok();
1777
1778 switch( tok )
1779 {
1780 case T_via:
1781 case T_wire:
1782 case T_via_keepout:
1783 case T_snap:
1784 case T_place:
1785 growth->grid_type = tok;
1786
1787 if( NextTok() != T_NUMBER )
1788 Expecting( T_NUMBER );
1789
1790 growth->dimension = strtod( CurText(), 0 );
1791 tok = NextTok();
1792
1793 if( tok == T_LEFT )
1794 {
1795 while( ( tok = NextTok() ) != T_RIGHT )
1796 {
1797 if( tok == T_direction )
1798 {
1799 if( growth->grid_type == T_place )
1800 Unexpected( tok );
1801
1802 tok = NextTok();
1803
1804 if( tok != T_x && tok != T_y )
1805 Unexpected( CurText() );
1806
1807 growth->direction = tok;
1808
1809 if( NextTok() != T_RIGHT )
1810 Expecting(T_RIGHT);
1811 }
1812 else if( tok == T_offset )
1813 {
1814 if( growth->grid_type == T_place )
1815 Unexpected( tok );
1816
1817 if( NextTok() != T_NUMBER )
1818 Expecting( T_NUMBER );
1819
1820 growth->offset = strtod( CurText(), 0 );
1821
1822 if( NextTok() != T_RIGHT )
1823 Expecting( T_RIGHT );
1824 }
1825 else if( tok == T_image_type )
1826 {
1827 if( growth->grid_type != T_place )
1828 Unexpected( tok );
1829
1830 tok = NextTok();
1831
1832 if( tok != T_smd && tok != T_pin )
1833 Unexpected( CurText() );
1834
1835 growth->image_type = tok;
1836
1837 if( NextTok() != T_RIGHT )
1838 Expecting( T_RIGHT );
1839 }
1840 }
1841 }
1842
1843 break;
1844
1845 default:
1846 Unexpected( tok );
1847 }
1848}

References DSN::GRID::dimension, DSN::GRID::direction, DSN::GRID::grid_type, DSN::GRID::image_type, and DSN::GRID::offset.

Referenced by doSTRUCTURE().

◆ doHISTORY()

void DSN::SPECCTRA_DB::doHISTORY ( HISTORY growth)
private

Definition at line 3314 of file specctra.cpp.

3315{
3316 T tok;
3317
3318 /* <history_descriptor >::=
3319 (history [{<ancestor_file_descriptor> }] <self_descriptor> )
3320 */
3321
3322 while( ( tok = NextTok() ) != T_RIGHT )
3323 {
3324 if( tok != T_LEFT )
3325 Expecting( T_LEFT );
3326
3327 tok = NextTok();
3328
3329 switch( tok )
3330 {
3331 case T_ancestor:
3332 ANCESTOR* ancestor;
3333 ancestor = new ANCESTOR( growth );
3334 growth->ancestors.push_back( ancestor );
3335 doANCESTOR( ancestor );
3336 break;
3337
3338 case T_self:
3339 while( ( tok = NextTok() ) != T_RIGHT )
3340 {
3341 if( tok != T_LEFT )
3342 Expecting( T_LEFT );
3343
3344 tok = NextTok();
3345
3346 switch( tok )
3347 {
3348 case T_created_time:
3349 readTIME( &growth->time_stamp );
3350 NeedRIGHT();
3351 break;
3352
3353 case T_comment:
3354 NeedSYMBOL();
3355 growth->comments.push_back( CurText() );
3356 NeedRIGHT();
3357 break;
3358
3359 default:
3360 Unexpected( CurText() );
3361 }
3362 }
3363
3364 break;
3365
3366 default:
3367 Unexpected( CurText() );
3368 }
3369 }
3370}
void doANCESTOR(ANCESTOR *growth)
Definition: specctra.cpp:3275

References DSN::HISTORY::ancestors, DSN::HISTORY::comments, doANCESTOR(), readTIME(), and DSN::HISTORY::time_stamp.

Referenced by doSESSION().

◆ doIMAGE()

void DSN::SPECCTRA_DB::doIMAGE ( IMAGE growth)
private

Definition at line 2301 of file specctra.cpp.

2302{
2303 T tok = NextTok();
2304
2305 /* <image_descriptor >::=
2306 (image <image_id >
2307 [(side [front | back | both])]
2308 [<unit_descriptor> ]
2309 [<outline_descriptor> ]
2310 {(pin <padstack_id > [(rotate <rotation> )]
2311 [<reference_descriptor> | <pin_array_descriptor> ]
2312 [<user_property_descriptor> ])}
2313 [{<conductor_shape_descriptor> }]
2314 [{<conductor_via_descriptor> }]
2315 [<rule_descriptor> ]
2316 [<place_rule_descriptor> ]
2317 [{<keepout_descriptor> }]
2318 [<image_property_descriptor> ]
2319 )
2320 */
2321
2322 if( !IsSymbol( tok ) && tok != T_NUMBER )
2323 Expecting( "image_id" );
2324
2325 growth->image_id = CurText();
2326
2327 while( ( tok = NextTok() ) != T_RIGHT )
2328 {
2329 if( tok != T_LEFT )
2330 Expecting( T_LEFT );
2331
2332 tok = NextTok();
2333
2334 switch( tok )
2335 {
2336 case T_unit:
2337 if( growth->unit )
2338 Unexpected( tok );
2339
2340 growth->unit = new UNIT_RES( growth, tok );
2341 doUNIT( growth->unit );
2342 break;
2343
2344 case T_side:
2345 tok = NextTok();
2346
2347 if( tok != T_front && tok != T_back && tok != T_both )
2348 Expecting( "front|back|both" );
2349
2350 growth->side = tok;
2351 NeedRIGHT();
2352 break;
2353
2354 case T_outline:
2355 SHAPE* outline;
2356 outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
2357 growth->Append( outline );
2358 doSHAPE( outline );
2359 break;
2360
2361 case T_pin:
2362 PIN* pin;
2363 pin = new PIN( growth );
2364 growth->pins.push_back( pin );
2365 doPIN( pin );
2366 break;
2367
2368 case T_rule:
2369 if( growth->rules )
2370 Unexpected( tok );
2371
2372 growth->rules = new RULE( growth, tok );
2373 doRULE( growth->rules );
2374 break;
2375
2376 case T_place_rule:
2377 if( growth->place_rules )
2378 Unexpected( tok );
2379
2380 growth->place_rules = new RULE( growth, tok );
2381 doRULE( growth->place_rules );
2382 break;
2383
2384 case T_keepout:
2385 case T_place_keepout:
2386 case T_via_keepout:
2387 case T_wire_keepout:
2388 case T_bend_keepout:
2389 case T_elongate_keepout:
2390 KEEPOUT* keepout;
2391 keepout = new KEEPOUT( growth, tok );
2392 growth->keepouts.push_back( keepout );
2393 doKEEPOUT( keepout );
2394 break;
2395
2396 default:
2397 Unexpected( CurText() );
2398 }
2399 }
2400}
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595
void doSHAPE(SHAPE *growth)
Definition: specctra.cpp:2213
void doKEEPOUT(KEEPOUT *growth)
Definition: specctra.cpp:843
void doPIN(PIN *growth)
Definition: specctra.cpp:2403
An abstract shape on 2D plane.
Definition: shape.h:123

References DSN::ELEM_HOLDER::Append(), doKEEPOUT(), doPIN(), doRULE(), doSHAPE(), doUNIT(), DSN::IMAGE::image_id, DSN::IMAGE::keepouts, PIN, pin, DSN::IMAGE::pins, DSN::IMAGE::place_rules, RULE, DSN::IMAGE::rules, DSN::IMAGE::side, and DSN::IMAGE::unit.

Referenced by doLIBRARY().

◆ doKEEPOUT()

void DSN::SPECCTRA_DB::doKEEPOUT ( KEEPOUT growth)
private

Definition at line 843 of file specctra.cpp.

844{
845 T tok = NextTok();
846
847 if( IsSymbol(tok) )
848 {
849 growth->name = CurText();
850 tok = NextTok();
851 }
852
853 if( tok!=T_LEFT )
854 Expecting( T_LEFT );
855
856 while( tok != T_RIGHT )
857 {
858 if( tok!=T_LEFT )
859 Expecting( T_LEFT );
860
861 tok = NextTok();
862
863 switch( tok )
864 {
865 case T_sequence_number:
866 if( NextTok() != T_NUMBER )
867 Expecting( T_NUMBER );
868
869 growth->sequence_number = atoi( CurText() );
870 NeedRIGHT();
871 break;
872
873 case T_rule:
874 if( growth->rules )
875 Unexpected( tok );
876
877 growth->rules = new RULE( growth, T_rule );
878 doRULE( growth->rules );
879 break;
880
881 case T_place_rule:
882 if( growth->place_rules )
883 Unexpected( tok );
884
885 growth->place_rules = new RULE( growth, T_place_rule );
886 doRULE( growth->place_rules );
887 break;
888
889 case T_rect:
890 if( growth->shape )
891 Unexpected( tok );
892
893 growth->shape = new RECTANGLE( growth );
894 doRECTANGLE( (RECTANGLE*) growth->shape );
895 break;
896
897 case T_circle:
898 if( growth->shape )
899 Unexpected( tok );
900
901 growth->shape = new CIRCLE( growth );
902 doCIRCLE( (CIRCLE*) growth->shape );
903 break;
904
905 case T_polyline_path:
906 tok = T_path;
908
909 case T_path:
910 case T_polygon:
911 if( growth->shape )
912 Unexpected( tok );
913
914 growth->shape = new PATH( growth, tok );
915 doPATH( (PATH*) growth->shape );
916 break;
917
918 case T_qarc:
919 if( growth->shape )
920 Unexpected( tok );
921
922 growth->shape = new QARC( growth );
923 doQARC( (QARC*) growth->shape );
924 break;
925
926 case T_window:
927 WINDOW* window;
928 window = new WINDOW( growth );
929 growth->windows.push_back( window );
930 doWINDOW( window );
931 break;
932
933 default:
934 Unexpected( CurText() );
935 }
936
937 tok = NextTok();
938 }
939}
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1166
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:977
void doQARC(QARC *growth)
Definition: specctra.cpp:1197
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83

References CIRCLE, doCIRCLE(), doPATH(), doQARC(), doRECTANGLE(), doRULE(), doWINDOW(), KI_FALLTHROUGH, DSN::KEEPOUT::name, DSN::KEEPOUT::place_rules, RECTANGLE, RULE, DSN::KEEPOUT::rules, DSN::KEEPOUT::sequence_number, DSN::KEEPOUT::shape, and DSN::KEEPOUT::windows.

Referenced by doIMAGE(), and doSTRUCTURE().

◆ doLAYER()

void DSN::SPECCTRA_DB::doLAYER ( LAYER growth)
private

Definition at line 1349 of file specctra.cpp.

1350{
1351 T tok = NextTok();
1352
1353 if( !IsSymbol( tok ) )
1354 Expecting( T_SYMBOL );
1355
1356 growth->name = CurText();
1357
1358 while( ( tok = NextTok() ) != T_RIGHT )
1359 {
1360 if( tok != T_LEFT )
1361 Expecting( T_LEFT );
1362
1363 tok = NextTok();
1364
1365 switch( tok )
1366 {
1367 case T_type:
1368 tok = NextTok();
1369
1370 if( tok != T_signal && tok != T_power && tok != T_mixed && tok != T_jumper )
1371 Expecting( "signal|power|mixed|jumper" );
1372
1373 growth->layer_type = tok;
1374
1375 if( NextTok()!=T_RIGHT )
1376 Expecting(T_RIGHT);
1377
1378 break;
1379
1380 case T_rule:
1381 growth->rules = new RULE( growth, T_rule );
1382 doRULE( growth->rules );
1383 break;
1384
1385 case T_property:
1386 doPROPERTIES( &growth->properties );
1387 break;
1388
1389 case T_direction:
1390 tok = NextTok();
1391
1392 switch( tok )
1393 {
1394 case T_horizontal:
1395 case T_vertical:
1396 case T_orthogonal:
1397 case T_positive_diagonal:
1398 case T_negative_diagonal:
1399 case T_diagonal:
1400 case T_off:
1401 growth->direction = tok;
1402 break;
1403 default:
1404 // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
1405 if( !strcmp( "hori", CurText() ) )
1406 {
1407 growth->direction = T_horizontal;
1408 break;
1409 }
1410 else if( !strcmp( "vert", CurText() ) )
1411 {
1412 growth->direction = T_vertical;
1413 break;
1414 }
1415
1416 Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|"
1417 "diagonal|off" );
1418 }
1419
1420 if( NextTok() != T_RIGHT )
1421 Expecting( T_RIGHT );
1422
1423 break;
1424
1425 case T_cost:
1426 tok = NextTok();
1427
1428 switch( tok )
1429 {
1430 case T_forbidden:
1431 case T_high:
1432 case T_medium:
1433 case T_low:
1434 case T_free:
1435 growth->cost = tok;
1436 break;
1437 case T_NUMBER:
1438 // store as negative so we can differentiate between
1439 // T (positive) and T_NUMBER (negative)
1440 growth->cost = -atoi( CurText() );
1441 break;
1442 default:
1443 Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
1444 }
1445
1446 tok = NextTok();
1447
1448 if( tok == T_LEFT )
1449 {
1450 if( NextTok() != T_type )
1451 Unexpected( CurText() );
1452
1453 tok = NextTok();
1454
1455 if( tok!=T_length && tok!=T_way )
1456 Expecting( "length|way" );
1457
1458 growth->cost_type = tok;
1459
1460 if( NextTok()!=T_RIGHT )
1461 Expecting( T_RIGHT );
1462
1463 tok = NextTok();
1464 }
1465
1466 if( tok != T_RIGHT )
1467 Expecting( T_RIGHT );
1468
1469 break;
1470
1471 case T_use_net:
1472 while( ( tok = NextTok() ) != T_RIGHT )
1473 {
1474 if( !IsSymbol( tok ) )
1475 Expecting( T_SYMBOL );
1476
1477 growth->use_net.push_back( CurText() );
1478 }
1479
1480 break;
1481
1482 default:
1483 Unexpected( CurText() );
1484 }
1485 }
1486}
void doPROPERTIES(PROPERTIES *growth)
Definition: specctra.cpp:1326

References DSN::LAYER::cost, DSN::LAYER::cost_type, DSN::LAYER::direction, doPROPERTIES(), doRULE(), DSN::LAYER::layer_type, DSN::LAYER::name, DSN::LAYER::properties, RULE, DSN::LAYER::rules, and DSN::LAYER::use_net.

Referenced by doSTRUCTURE(), and doSTRUCTURE_OUT().

◆ doLAYER_NOISE_WEIGHT()

void DSN::SPECCTRA_DB::doLAYER_NOISE_WEIGHT ( LAYER_NOISE_WEIGHT growth)
private

Definition at line 633 of file specctra.cpp.

635{
636 T tok;
637
638 while( ( tok = NextTok() ) != T_RIGHT )
639 {
640 if( tok != T_LEFT )
641 Expecting( T_LEFT );
642
643 if( NextTok() != T_layer_pair )
644 Expecting( T_layer_pair );
645
646 SPECCTRA_LAYER_PAIR* layer_pair = new SPECCTRA_LAYER_PAIR( growth );
647 growth->layer_pairs.push_back( layer_pair );
648 doSPECCTRA_LAYER_PAIR( layer_pair );
649 }
650}
void doSPECCTRA_LAYER_PAIR(SPECCTRA_LAYER_PAIR *growth)
Definition: specctra.cpp:616

References doSPECCTRA_LAYER_PAIR(), and DSN::LAYER_NOISE_WEIGHT::layer_pairs.

Referenced by doSTRUCTURE().

◆ doLAYER_RULE()

void DSN::SPECCTRA_DB::doLAYER_RULE ( LAYER_RULE growth)
private

Definition at line 1851 of file specctra.cpp.

1852{
1853 T tok;
1854
1855 NeedSYMBOL();
1856
1857 do
1858 {
1859 growth->layer_ids.push_back( CurText() );
1860
1861 } while( IsSymbol( tok = NextTok() ) );
1862
1863 if( tok != T_LEFT )
1864 Expecting( T_LEFT );
1865
1866 if( NextTok() != T_rule )
1867 Expecting( T_rule );
1868
1869 growth->rule = new RULE( growth, T_rule );
1870 doRULE( growth->rule );
1871
1872 NeedRIGHT();
1873}

References doRULE(), DSN::LAYER_RULE::layer_ids, RULE, and DSN::LAYER_RULE::rule.

Referenced by doCLASS(), doCLASS_CLASS(), doFROMTO(), and doNET().

◆ doLIBRARY()

void DSN::SPECCTRA_DB::doLIBRARY ( LIBRARY growth)
private

Definition at line 2454 of file specctra.cpp.

2455{
2456 T tok;
2457
2458 /* <library_descriptor >::=
2459 (library
2460 [<unit_descriptor> ]
2461 {<image_descriptor> }
2462 [{<jumper_descriptor> }]
2463 {<padstack_descriptor> }
2464 {<via_array_template_descriptor> }
2465 [<directory_descriptor> ]
2466 [<extra_image_directory_descriptor> ]
2467 [{<family_family_descriptor> }]
2468 [{<image_image_descriptor> }]
2469 )
2470 */
2471
2472 while( ( tok = NextTok() ) != T_RIGHT )
2473 {
2474 if( tok != T_LEFT )
2475 Expecting( T_LEFT );
2476
2477 tok = NextTok();
2478
2479 switch( tok )
2480 {
2481 case T_unit:
2482 if( growth->unit )
2483 Unexpected( tok );
2484
2485 growth->unit = new UNIT_RES( growth, tok );
2486 doUNIT( growth->unit );
2487 break;
2488
2489 case T_padstack:
2490 PADSTACK* padstack;
2491 padstack = new PADSTACK();
2492 growth->AddPadstack( padstack );
2493 doPADSTACK( padstack );
2494 break;
2495
2496 case T_image:
2497 IMAGE* image;
2498 image = new IMAGE( growth );
2499 growth->images.push_back( image );
2500 doIMAGE( image );
2501 break;
2502
2503 default:
2504 Unexpected( CurText() );
2505 }
2506 }
2507}
void doIMAGE(IMAGE *growth)
Definition: specctra.cpp:2301
void doPADSTACK(PADSTACK *growth)
Definition: specctra.cpp:2101
Manage an 8-bit channel image.
Definition: image.h:90

References DSN::LIBRARY::AddPadstack(), doIMAGE(), doPADSTACK(), doUNIT(), IMAGE, image, DSN::LIBRARY::images, and DSN::LIBRARY::unit.

Referenced by doPCB(), and doROUTE().

◆ doNET()

void DSN::SPECCTRA_DB::doNET ( NET growth)
private

Definition at line 2510 of file specctra.cpp.

2511{
2512 T tok = NextTok();
2513 PIN_REFS* pin_refs;
2514
2515 /* <net_descriptor >::=
2516 (net <net_id >
2517 [(unassigned)]
2518 [(net_number <integer >)]
2519 [(pins {<pin_reference> }) | (order {<pin_reference> })]
2520 [<component_order_descriptor> ]
2521 [(type [fix | normal])]
2522 [<user_property_descriptor> ]
2523 [<circuit_descriptor> ]
2524 [<rule_descriptor> ]
2525 [{<layer_rule_descriptor> }]
2526 [<fromto_descriptor> ]
2527 [(expose {<pin_reference> })]
2528 [(noexpose {<pin_reference> })]
2529 [(source {<pin_reference> })]
2530 [(load {<pin_reference> })]
2531 [(terminator {<pin_reference> })]
2532 [(supply [power | ground])]
2533 )
2534 */
2535
2536 if( !IsSymbol( tok ) )
2537 Expecting( "net_id" );
2538
2539 growth->net_id = CurText();
2540
2541 while( ( tok = NextTok() ) != T_RIGHT )
2542 {
2543 if( tok != T_LEFT )
2544 Expecting( T_LEFT );
2545
2546 tok = NextTok();
2547
2548 switch( tok )
2549 {
2550 case T_unassigned:
2551 growth->unassigned = true;
2552 NeedRIGHT();
2553 break;
2554
2555 case T_net_number:
2556 if( NextTok() != T_NUMBER )
2557 Expecting( T_NUMBER );
2558
2559 growth->net_number = atoi( CurText() );
2560 NeedRIGHT();
2561 break;
2562
2563 case T_pins:
2564 case T_order:
2565 growth->pins_type = tok;
2566 pin_refs = &growth->pins;
2567 goto L_pins;
2568
2569 case T_expose:
2570 pin_refs = &growth->expose;
2571 goto L_pins;
2572
2573 case T_noexpose:
2574 pin_refs = &growth->noexpose;
2575 goto L_pins;
2576
2577 case T_source:
2578 pin_refs = &growth->source;
2579 goto L_pins;
2580
2581 case T_load:
2582 pin_refs = &growth->load;
2583 goto L_pins;
2584
2585 case T_terminator:
2586 pin_refs = &growth->terminator;
2587 //goto L_pins;
2588
2589L_pins:
2590 {
2591 PIN_REF empty( growth );
2592
2593 while( ( tok = NextTok() ) != T_RIGHT )
2594 {
2595 // copy the empty one, then fill its copy later thru pin_ref.
2596 pin_refs->push_back( empty );
2597
2598 PIN_REF* pin_ref = &pin_refs->back();
2599
2600 readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
2601 }
2602 }
2603
2604 break;
2605
2606 case T_comp_order:
2607 if( growth->comp_order )
2608 Unexpected( tok );
2609
2610 growth->comp_order = new COMP_ORDER( growth );
2611 doCOMP_ORDER( growth->comp_order );
2612 break;
2613
2614 case T_type:
2615 tok = NextTok();
2616
2617 if( tok!=T_fix && tok!=T_normal )
2618 Expecting( "fix|normal" );
2619
2620 growth->type = tok;
2621 NeedRIGHT();
2622 break;
2623
2624/* @todo
2625 case T_circuit:
2626 break;
2627*/
2628
2629 case T_rule:
2630 if( growth->rules )
2631 Unexpected( tok );
2632
2633 growth->rules = new RULE( growth, T_rule );
2634 doRULE( growth->rules );
2635 break;
2636
2637 case T_layer_rule:
2638 LAYER_RULE* layer_rule;
2639 layer_rule = new LAYER_RULE( growth );
2640 growth->layer_rules.push_back( layer_rule );
2641 doLAYER_RULE( layer_rule );
2642 break;
2643
2644 case T_fromto:
2645 FROMTO* fromto;
2646 fromto = new FROMTO( growth );
2647 growth->fromtos.push_back( fromto );
2648 doFROMTO( fromto );
2649 break;
2650
2651 default:
2652 Unexpected( CurText() );
2653 }
2654 }
2655}
void doCOMP_ORDER(COMP_ORDER *growth)
Definition: specctra.cpp:2856
void doFROMTO(FROMTO *growth)
Definition: specctra.cpp:2874
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen.
Definition: specctra.cpp:137
static bool empty(const wxTextEntryBase *aCtrl)
std::vector< PIN_REF > PIN_REFS
Definition: specctra.h:2485

References DSN::NET::comp_order, DSN::PIN_REF::component_id, doCOMP_ORDER(), doFROMTO(), doLAYER_RULE(), doRULE(), empty(), DSN::NET::expose, DSN::NET::fromtos, DSN::NET::layer_rules, DSN::NET::load, DSN::NET::net_id, DSN::NET::net_number, DSN::NET::noexpose, DSN::PIN_REF::pin_id, DSN::NET::pins, DSN::NET::pins_type, readCOMPnPIN(), RULE, DSN::NET::rules, DSN::NET::source, DSN::NET::terminator, DSN::NET::type, and DSN::NET::unassigned.

Referenced by doNETWORK().

◆ doNET_OUT()

void DSN::SPECCTRA_DB::doNET_OUT ( NET_OUT growth)
private

Definition at line 3587 of file specctra.cpp.

3588{
3589 T tok;
3590
3591 /* <net_out_descriptor >::=
3592 (net <net_id >
3593 [(net_number <integer >)]
3594 [<rule_descriptor> ]
3595 {[<wire_shape_descriptor> | <wire_guide_descriptor> |
3596 <wire_via_descriptor> | <bond_shape_descriptor> ]}
3597 {[<supply_pin_descriptor> ]}
3598 )
3599 */
3600
3601 NeedSYMBOLorNUMBER();
3602 growth->net_id = CurText();
3603
3604 while( ( tok = NextTok() ) != T_RIGHT )
3605 {
3606 if( tok != T_LEFT )
3607 Expecting( T_LEFT );
3608
3609 tok = NextTok();
3610
3611 switch( tok )
3612 {
3613 case T_net_number:
3614 tok = NextTok();
3615
3616 if( tok!= T_NUMBER )
3617 Expecting( T_NUMBER );
3618
3619 growth->net_number = atoi( CurText() );
3620 NeedRIGHT();
3621 break;
3622
3623 case T_rule:
3624 if( growth->rules )
3625 Unexpected( tok );
3626
3627 growth->rules = new RULE( growth, tok );
3628 doRULE( growth->rules );
3629 break;
3630
3631 case T_wire:
3632 WIRE* wire;
3633 wire = new WIRE( growth );
3634 growth->wires.push_back( wire );
3635 doWIRE( wire );
3636 break;
3637
3638 case T_via:
3639 WIRE_VIA* wire_via;
3640 wire_via = new WIRE_VIA( growth );
3641 growth->wire_vias.push_back( wire_via );
3642 doWIRE_VIA( wire_via );
3643 break;
3644
3645 case T_supply_pin:
3646 SUPPLY_PIN* supply_pin;
3647 supply_pin = new SUPPLY_PIN( growth );
3648 growth->supply_pins.push_back( supply_pin );
3649 doSUPPLY_PIN( supply_pin );
3650 break;
3651
3652 default:
3653 Unexpected( CurText() );
3654 }
3655 }
3656}
void doWIRE(WIRE *growth)
Definition: specctra.cpp:2967
void doSUPPLY_PIN(SUPPLY_PIN *growth)
Definition: specctra.cpp:3659
void doWIRE_VIA(WIRE_VIA *growth)
Definition: specctra.cpp:3101

References doRULE(), doSUPPLY_PIN(), doWIRE(), doWIRE_VIA(), DSN::NET_OUT::net_id, DSN::NET_OUT::net_number, RULE, DSN::NET_OUT::rules, DSN::NET_OUT::supply_pins, WIRE, DSN::NET_OUT::wire_vias, and DSN::NET_OUT::wires.

Referenced by doROUTE().

◆ doNETWORK()

void DSN::SPECCTRA_DB::doNETWORK ( NETWORK growth)
private

Definition at line 2810 of file specctra.cpp.

2811{
2812 T tok;
2813
2814 /* <network_descriptor >::=
2815 (network
2816 {<net_descriptor>}
2817 [{<class_descriptor> }]
2818 [{<class_class_descriptor> }]
2819 [{<group_descriptor> }]
2820 [{<group_set_descriptor> }]
2821 [{<pair_descriptor> }]
2822 [{<bundle_descriptor> }]
2823 )
2824 */
2825
2826 while( ( tok = NextTok() ) != T_RIGHT )
2827 {
2828 if( tok != T_LEFT )
2829 Expecting( T_LEFT );
2830
2831 tok = NextTok();
2832
2833 switch( tok )
2834 {
2835 case T_net:
2836 NET* net;
2837 net = new NET( growth );
2838 growth->nets.push_back( net );
2839 doNET( net );
2840 break;
2841
2842 case T_class:
2843 CLASS* myclass;
2844 myclass = new CLASS( growth );
2845 growth->classes.push_back( myclass );
2846 doCLASS( myclass );
2847 break;
2848
2849 default:
2850 Unexpected( CurText() );
2851 }
2852 }
2853}
void doCLASS(CLASS *growth)
Definition: specctra.cpp:2697
void doNET(NET *growth)
Definition: specctra.cpp:2510
@ NET
This item represents a net.

References DSN::NETWORK::classes, doCLASS(), doNET(), NET, and DSN::NETWORK::nets.

Referenced by doPCB().

◆ doPADSTACK()

void DSN::SPECCTRA_DB::doPADSTACK ( PADSTACK growth)
private

Definition at line 2101 of file specctra.cpp.

2102{
2103 T tok = NextTok();
2104
2105 /* (padstack <padstack_id >
2106 [<unit_descriptor> ]
2107 {(shape <shape_descriptor>
2108 [<reduced_shape_descriptor> ]
2109 [(connect [on | off])]
2110 [{<window_descriptor> }]
2111 )}
2112 [<attach_descriptor> ]
2113 [{<pad_via_site_descriptor> }]
2114 [(rotate [on | off])]
2115 [(absolute [on | off])]
2116 [(rule <clearance_descriptor> )])
2117 */
2118
2119 // padstack_id may be a number
2120 if( !IsSymbol( tok ) && tok != T_NUMBER )
2121 Expecting( "padstack_id" );
2122
2123 growth->padstack_id = CurText();
2124
2125 while( ( tok = NextTok() ) != T_RIGHT )
2126 {
2127 if( tok != T_LEFT )
2128 Expecting( T_LEFT );
2129
2130 tok = NextTok();
2131
2132 switch( tok )
2133 {
2134 case T_unit:
2135 if( growth->unit )
2136 Unexpected( tok );
2137
2138 growth->unit = new UNIT_RES( growth, tok );
2139 doUNIT( growth->unit );
2140 break;
2141
2142 case T_rotate:
2143 tok = NextTok();
2144
2145 if( tok != T_on && tok != T_off )
2146 Expecting( "on|off" );
2147
2148 growth->rotate = tok;
2149 NeedRIGHT();
2150 break;
2151
2152 case T_absolute:
2153 tok = NextTok();
2154
2155 if( tok != T_on && tok != T_off )
2156 Expecting( "on|off" );
2157
2158 growth->absolute = tok;
2159 NeedRIGHT();
2160 break;
2161
2162 case T_shape:
2163 SHAPE* shape;
2164 shape = new SHAPE( growth );
2165 growth->Append( shape );
2166 doSHAPE( shape );
2167 break;
2168
2169 case T_attach:
2170 tok = NextTok();
2171
2172 if( tok != T_off && tok != T_on )
2173 Expecting( "off|on" );
2174
2175 growth->attach = tok;
2176 tok = NextTok();
2177
2178 if( tok == T_LEFT )
2179 {
2180 if( NextTok() != T_use_via )
2181 Expecting( T_use_via );
2182
2183 NeedSYMBOL();
2184 growth->via_id = CurText();
2185
2186 NeedRIGHT();
2187 NeedRIGHT();
2188 }
2189
2190 break;
2191
2192 /*
2193 case T_via_site: not supported
2194 break;
2195 */
2196
2197 case T_rule:
2198
2199 if( growth->rules )
2200 Unexpected( tok );
2201
2202 growth->rules = new RULE( growth, T_rule );
2203 doRULE( growth->rules );
2204 break;
2205
2206 default:
2207 Unexpected( CurText() );
2208 }
2209 }
2210}

References DSN::PADSTACK::absolute, DSN::ELEM_HOLDER::Append(), DSN::PADSTACK::attach, doRULE(), doSHAPE(), doUNIT(), DSN::PADSTACK::padstack_id, DSN::PADSTACK::rotate, RULE, DSN::PADSTACK::rules, DSN::PADSTACK::unit, and DSN::PADSTACK::via_id.

Referenced by doLIBRARY().

◆ doPARSER()

void DSN::SPECCTRA_DB::doPARSER ( PARSER growth)
private

Definition at line 412 of file specctra.cpp.

413{
414 T tok;
415 std::string const1;
416 std::string const2;
417
418 /* <parser_descriptor >::=
419 (parser
420 [(string_quote <quote_char >)]
421 (space_in_quoted_tokens [on | off])
422 [(host_cad <id >)]
423 [(host_version <id >)]
424 [{(constant <id > <id >)}]
425 [(write_resolution] {<character> <positive_integer >})]
426 [(routes_include {[testpoint | guides |
427 image_conductor]})]
428 [(wires_include testpoint)]
429 [(case_sensitive [on | off])]
430 [(via_rotate_first [on | off])]
431 )
432 */
433
434 while( (tok = NextTok()) != T_RIGHT )
435 {
436 if( tok != T_LEFT )
437 Expecting( T_LEFT );
438
439 tok = NextTok();
440
441 switch( tok )
442 {
443 case T_STRING_QUOTE:
444 tok = NextTok();
445
446 if( tok != T_QUOTE_DEF )
447 Expecting( T_QUOTE_DEF );
448
449 SetStringDelimiter( (unsigned char) *CurText() );
450 growth->string_quote = *CurText();
451 m_quote_char = CurText();
452 NeedRIGHT();
453 break;
454
455 case T_space_in_quoted_tokens:
456 tok = NextTok();
457
458 if( tok!=T_on && tok!=T_off )
459 Expecting( "on|off" );
460
461 SetSpaceInQuotedTokens( tok==T_on );
462 growth->space_in_quoted_tokens = (tok==T_on);
463 NeedRIGHT();
464 break;
465
466 case T_host_cad:
467 NeedSYMBOL();
468 growth->host_cad = CurText();
469 NeedRIGHT();
470 break;
471
472 case T_host_version:
473 NeedSYMBOLorNUMBER();
474 growth->host_version = CurText();
475 NeedRIGHT();
476 break;
477
478 case T_constant:
479 NeedSYMBOLorNUMBER();
480 const1 = CurText();
481 NeedSYMBOLorNUMBER();
482 const2 = CurText();
483 NeedRIGHT();
484 growth->constants.push_back( const1 );
485 growth->constants.push_back( const2 );
486 break;
487
488 case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
489 while( (tok = NextTok()) != T_RIGHT )
490 {
491 if( tok!=T_SYMBOL )
492 Expecting( T_SYMBOL );
493
494 tok = NextTok();
495
496 if( tok!=T_NUMBER )
497 Expecting( T_NUMBER );
498
499 // @todo
500 }
501
502 break;
503
504 case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
505 while( (tok = NextTok()) != T_RIGHT )
506 {
507 switch( tok )
508 {
509 case T_testpoint:
510 growth->routes_include_testpoint = true;
511 break;
512 case T_guide:
513 growth->routes_include_guides = true;
514 break;
515 case T_image_conductor:
516 growth->routes_include_image_conductor = true;
517 break;
518 default:
519 Expecting( "testpoint|guides|image_conductor" );
520 }
521 }
522
523 break;
524
525 case T_wires_include: // [(wires_include testpoint)]
526 tok = NextTok();
527
528 if( tok != T_testpoint )
529 Expecting( T_testpoint );
530
531 growth->routes_include_testpoint = true;
532 NeedRIGHT();
533 break;
534
535 case T_case_sensitive:
536 tok = NextTok();
537
538 if( tok!=T_on && tok!=T_off )
539 Expecting( "on|off" );
540
541 growth->case_sensitive = (tok==T_on);
542 NeedRIGHT();
543 break;
544
545 case T_via_rotate_first: // [(via_rotate_first [on | off])]
546 tok = NextTok();
547
548 if( tok!=T_on && tok!=T_off )
549 Expecting( "on|off" );
550
551 growth->via_rotate_first = (tok==T_on);
552 NeedRIGHT();
553 break;
554
555 case T_generated_by_freeroute:
556 growth->generated_by_freeroute = true;
557 NeedRIGHT();
558 break;
559
560 default:
561 Unexpected( CurText() );
562 }
563 }
564}

References DSN::PARSER::case_sensitive, DSN::PARSER::constants, DSN::PARSER::generated_by_freeroute, DSN::PARSER::host_cad, DSN::PARSER::host_version, m_quote_char, DSN::PARSER::routes_include_guides, DSN::PARSER::routes_include_image_conductor, DSN::PARSER::routes_include_testpoint, DSN::PARSER::space_in_quoted_tokens, DSN::PARSER::string_quote, and DSN::PARSER::via_rotate_first.

Referenced by doPCB(), and doROUTE().

◆ doPATH()

void DSN::SPECCTRA_DB::doPATH ( PATH growth)
private

Definition at line 1086 of file specctra.cpp.

1087{
1088 T tok = NextTok();
1089
1090 if( !IsSymbol( tok ) && tok != T_NUMBER ) // a layer name can be like a number like +12
1091 Expecting( "layer_id" );
1092
1093 growth->layer_id = CurText();
1094
1095 if( NextTok() != T_NUMBER )
1096 Expecting( "aperture_width" );
1097
1098 growth->aperture_width = strtod( CurText(), nullptr );
1099
1100 POINT ptTemp;
1101
1102 tok = NextTok();
1103
1104 do
1105 {
1106 if( tok != T_NUMBER )
1107 Expecting( T_NUMBER );
1108
1109 ptTemp.x = strtod( CurText(), nullptr );
1110
1111 if( NextTok() != T_NUMBER )
1112 Expecting( T_NUMBER );
1113
1114 ptTemp.y = strtod( CurText(), nullptr );
1115
1116 growth->points.push_back( ptTemp );
1117
1118 } while( ( tok = NextTok() ) != T_RIGHT && tok != T_LEFT );
1119
1120 if( tok == T_LEFT )
1121 {
1122 if( NextTok() != T_aperture_type )
1123 Expecting( T_aperture_type );
1124
1125 tok = NextTok();
1126
1127 if( tok!=T_round && tok!=T_square )
1128 Expecting( "round|square" );
1129
1130 growth->aperture_type = tok;
1131
1132 NeedRIGHT();
1133 }
1134}

References DSN::PATH::aperture_type, DSN::PATH::aperture_width, DSN::PATH::layer_id, DSN::PATH::points, DSN::POINT::x, and DSN::POINT::y.

Referenced by doBOUNDARY(), doKEEPOUT(), doREGION(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doPCB()

void DSN::SPECCTRA_DB::doPCB ( PCB growth)
private

Definition at line 297 of file specctra.cpp.

298{
299 T tok;
300
301 /* <design_descriptor >::=
302 (pcb <pcb_id >
303 [<parser_descriptor> ]
304 [<capacitance_resolution_descriptor> ]
305 [<conductance_resolution_descriptor> ]
306 [<current_resolution_descriptor> ]
307 [<inductance_resolution_descriptor> ]
308 [<resistance_resolution_descriptor> ]
309 [<resolution_descriptor> ]
310 [<time_resolution_descriptor> ]
311 [<voltage_resolution_descriptor> ]
312 [<unit_descriptor> ]
313 [<structure_descriptor> | <file_descriptor> ]
314 [<placement_descriptor> | <file_descriptor> ]
315 [<library_descriptor> | <file_descriptor> ]
316 [<floor_plan_descriptor> | <file_descriptor> ]
317 [<part_library_descriptor> | <file_descriptor> ]
318 [<network_descriptor> | <file_descriptor> ]
319 [<wiring_descriptor> ]
320 [<color_descriptor> ]
321 )
322 */
323
324 NeedSYMBOL();
325 growth->pcbname = CurText();
326
327 while( (tok = NextTok()) != T_RIGHT )
328 {
329 if( tok != T_LEFT )
330 Expecting( T_LEFT );
331
332 tok = NextTok();
333
334 switch( tok )
335 {
336 case T_parser:
337 if( growth->parser )
338 Unexpected( tok );
339
340 growth->parser = new PARSER( growth );
341 doPARSER( growth->parser );
342 break;
343
344 case T_unit:
345 if( growth->unit )
346 Unexpected( tok );
347
348 growth->unit = new UNIT_RES( growth, tok );
349 doUNIT( growth->unit );
350 break;
351
352 case T_resolution:
353 if( growth->resolution )
354 Unexpected( tok );
355
356 growth->resolution = new UNIT_RES( growth, tok );
357 doRESOLUTION( growth->resolution );
358 break;
359
360 case T_structure:
361 if( growth->structure )
362 Unexpected( tok );
363
364 growth->structure = new STRUCTURE( growth );
365 doSTRUCTURE( growth->structure );
366 break;
367
368 case T_placement:
369 if( growth->placement )
370 Unexpected( tok );
371
372 growth->placement = new PLACEMENT( growth );
373 doPLACEMENT( growth->placement );
374 break;
375
376 case T_library:
377 if( growth->library )
378 Unexpected( tok );
379
380 growth->library = new LIBRARY( growth );
381 doLIBRARY( growth->library );
382 break;
383
384 case T_network:
385 if( growth->network )
386 Unexpected( tok );
387
388 growth->network = new NETWORK( growth );
389 doNETWORK( growth->network );
390 break;
391
392 case T_wiring:
393 if( growth->wiring )
394 Unexpected( tok );
395
396 growth->wiring = new WIRING( growth );
397 doWIRING( growth->wiring );
398 break;
399
400 default:
401 Unexpected( CurText() );
402 }
403 }
404
405 tok = NextTok();
406
407 if( tok != T_EOF )
408 Expecting( T_EOF );
409}
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:2043
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:567
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2454
void doPARSER(PARSER *growth)
Definition: specctra.cpp:412
void doNETWORK(NETWORK *growth)
Definition: specctra.cpp:2810
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:653
void doWIRING(WIRING *growth)
Definition: specctra.cpp:3216

References doLIBRARY(), doNETWORK(), doPARSER(), doPLACEMENT(), doRESOLUTION(), doSTRUCTURE(), doUNIT(), doWIRING(), DSN::PCB::library, DSN::PCB::network, DSN::PCB::parser, DSN::PCB::pcbname, DSN::PCB::placement, DSN::PCB::resolution, DSN::PCB::structure, DSN::PCB::unit, and DSN::PCB::wiring.

Referenced by LoadPCB().

◆ doPIN()

void DSN::SPECCTRA_DB::doPIN ( PIN growth)
private

Definition at line 2403 of file specctra.cpp.

2404{
2405 T tok = NextTok();
2406
2407 /* (pin <padstack_id > [(rotate <rotation> )]
2408 [<reference_descriptor> | <pin_array_descriptor> ]
2409 [<user_property_descriptor> ])
2410 */
2411
2412 // a padstack_id may be a number
2413 if( !IsSymbol( tok ) && tok!=T_NUMBER )
2414 Expecting( "padstack_id" );
2415
2416 growth->padstack_id = CurText();
2417
2418 while( ( tok = NextTok() ) != T_RIGHT )
2419 {
2420 if( tok == T_LEFT )
2421 {
2422 tok = NextTok();
2423
2424 if( tok != T_rotate )
2425 Expecting( T_rotate );
2426
2427 if( NextTok() != T_NUMBER )
2428 Expecting( T_NUMBER );
2429
2430 growth->SetRotation( strtod( CurText(), 0 ) );
2431 NeedRIGHT();
2432 }
2433 else
2434 {
2435 if( !IsSymbol( tok ) && tok != T_NUMBER )
2436 Expecting( "pin_id" );
2437
2438 growth->pin_id = CurText();
2439
2440 if( NextTok() != T_NUMBER )
2441 Expecting( T_NUMBER );
2442
2443 growth->vertex.x = strtod( CurText(), 0 );
2444
2445 if( NextTok() != T_NUMBER )
2446 Expecting( T_NUMBER );
2447
2448 growth->vertex.y = strtod( CurText(), 0 );
2449 }
2450 }
2451}

References DSN::PIN::padstack_id, DSN::PIN::pin_id, DSN::PIN::SetRotation(), DSN::PIN::vertex, DSN::POINT::x, and DSN::POINT::y.

Referenced by doIMAGE().

◆ doPLACE()

void DSN::SPECCTRA_DB::doPLACE ( PLACE growth)
private

Definition at line 1876 of file specctra.cpp.

1877{
1878 T tok = NextTok();
1879
1880 if( !IsSymbol( tok ) )
1881 Expecting( "component_id" );
1882
1883 growth->component_id = CurText();
1884
1885 tok = NextTok();
1886
1887 if( tok == T_NUMBER )
1888 {
1889 POINT point;
1890
1891 point.x = strtod( CurText(), 0 );
1892
1893 if( NextTok() != T_NUMBER )
1894 Expecting( T_NUMBER );
1895
1896 point.y = strtod( CurText(), 0 );
1897
1898 growth->SetVertex( point );
1899
1900 tok = NextTok();
1901
1902 if( tok != T_front && tok != T_back )
1903 Expecting( "front|back" );
1904
1905 growth->side = tok;
1906
1907 if( NextTok() != T_NUMBER )
1908 Expecting( "rotation" );
1909
1910 growth->SetRotation( strtod( CurText(), 0 ) );
1911 }
1912
1913 while( ( tok = NextTok() ) != T_RIGHT )
1914 {
1915 if( tok != T_LEFT )
1916 Expecting( T_LEFT );
1917
1918 tok = NextTok();
1919
1920 switch( tok )
1921 {
1922 case T_mirror:
1923 tok = NextTok();
1924
1925 if( tok == T_x || tok == T_y || tok == T_xy || tok == T_off )
1926 growth->mirror = tok;
1927 else
1928 Expecting( "x|y|xy|off" );
1929
1930 break;
1931
1932 case T_status:
1933 tok = NextTok();
1934
1935 if( tok==T_added || tok==T_deleted || tok==T_substituted )
1936 growth->status = tok;
1937 else
1938 Expecting("added|deleted|substituted");
1939
1940 break;
1941
1942 case T_logical_part:
1943 if( growth->logical_part.size() )
1944 Unexpected( tok );
1945
1946 tok = NextTok();
1947
1948 if( !IsSymbol( tok ) )
1949 Expecting( "logical_part_id");
1950
1951 growth->logical_part = CurText();
1952 break;
1953
1954 case T_place_rule:
1955 if( growth->place_rules )
1956 Unexpected( tok );
1957
1958 growth->place_rules = new RULE( growth, T_place_rule );
1959 doRULE( growth->place_rules );
1960 break;
1961
1962 case T_property:
1963 if( growth->properties.size() )
1964 Unexpected( tok );
1965
1966 doPROPERTIES( &growth->properties );
1967 break;
1968
1969 case T_lock_type:
1970 tok = NextTok();
1971
1972 if( tok == T_position || tok == T_gate || tok == T_subgate || tok == T_pin )
1973 growth->lock_type = tok;
1974 else
1975 Expecting( "position|gate|subgate|pin" );
1976
1977 break;
1978
1979 case T_rule:
1980 if( growth->rules || growth->region )
1981 Unexpected( tok );
1982
1983 growth->rules = new RULE( growth, T_rule );
1984 doRULE( growth->rules );
1985 break;
1986
1987 case T_region:
1988 if( growth->rules || growth->region )
1989 Unexpected( tok );
1990
1991 growth->region = new REGION( growth );
1992 doREGION( growth->region );
1993 break;
1994
1995 case T_pn:
1996 if( growth->part_number.size() )
1997 Unexpected( tok );
1998
1999 NeedSYMBOLorNUMBER();
2000 growth->part_number = CurText();
2001 NeedRIGHT();
2002 break;
2003
2004 default:
2005 Unexpected( tok );
2006 }
2007 }
2008}
void doREGION(REGION *growth)
Definition: specctra.cpp:1627

References DSN::PLACE::component_id, doPROPERTIES(), doREGION(), doRULE(), DSN::PLACE::lock_type, DSN::PLACE::logical_part, DSN::PLACE::mirror, DSN::PLACE::part_number, DSN::PLACE::place_rules, DSN::PLACE::properties, REGION, DSN::PLACE::region, RULE, DSN::PLACE::rules, DSN::PLACE::SetRotation(), DSN::PLACE::SetVertex(), DSN::PLACE::side, DSN::PLACE::status, DSN::POINT::x, and DSN::POINT::y.

Referenced by doCOMPONENT().

◆ doPLACEMENT()

void DSN::SPECCTRA_DB::doPLACEMENT ( PLACEMENT growth)
private

Definition at line 2043 of file specctra.cpp.

2044{
2045 T tok;
2046
2047 while( ( tok = NextTok() ) != T_RIGHT )
2048 {
2049 if( tok == T_EOF )
2050 Unexpected( T_EOF );
2051
2052 if( tok != T_LEFT )
2053 Expecting( T_LEFT );
2054
2055 tok = NextTok();
2056
2057 switch( tok )
2058 {
2059 case T_unit:
2060 case T_resolution:
2061 growth->unit = new UNIT_RES( growth, tok );
2062
2063 if( tok == T_resolution )
2064 doRESOLUTION( growth->unit );
2065 else
2066 doUNIT( growth->unit );
2067 break;
2068
2069 case T_place_control:
2070 NeedRIGHT();
2071 tok = NextTok();
2072
2073 if( tok != T_flip_style )
2074 Expecting( T_flip_style );
2075
2076 tok = NextTok();
2077
2078 if( tok == T_mirror_first || tok == T_rotate_first )
2079 growth->flip_style = tok;
2080 else
2081 Expecting( "mirror_first|rotate_first" );
2082
2083 NeedRIGHT();
2084 NeedRIGHT();
2085 break;
2086
2087 case T_component:
2088 COMPONENT* component;
2089 component = new COMPONENT( growth );
2090 growth->components.push_back( component );
2091 doCOMPONENT( component );
2092 break;
2093
2094 default:
2095 Unexpected( tok );
2096 }
2097 }
2098}
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:85
void doCOMPONENT(COMPONENT *growth)
Definition: specctra.cpp:2011

References COMPONENT, DSN::PLACEMENT::components, doCOMPONENT(), doRESOLUTION(), doUNIT(), DSN::PLACEMENT::flip_style, and DSN::PLACEMENT::unit.

Referenced by doPCB(), and doSESSION().

◆ doPROPERTIES()

void DSN::SPECCTRA_DB::doPROPERTIES ( PROPERTIES growth)
private

Definition at line 1326 of file specctra.cpp.

1327{
1328 T tok;
1329 PROPERTY property; // construct it once here, append multiple times.
1330
1331 while( ( tok = NextTok() ) != T_RIGHT )
1332 {
1333 if( tok != T_LEFT )
1334 Expecting( T_LEFT );
1335
1336 NeedSYMBOLorNUMBER();
1337 property.name = CurText();
1338
1339 NeedSYMBOLorNUMBER();
1340 property.value = CurText();
1341
1342 growth->push_back( property );
1343
1344 NeedRIGHT();
1345 }
1346}

Referenced by doLAYER(), and doPLACE().

◆ doQARC()

void DSN::SPECCTRA_DB::doQARC ( QARC growth)
private

Definition at line 1197 of file specctra.cpp.

1198{
1199 NeedSYMBOL();
1200 growth->layer_id = CurText();
1201
1202 if( NextTok() != T_NUMBER )
1203 Expecting( T_NUMBER );
1204
1205 growth->aperture_width = strtod( CurText(), 0 );
1206
1207 for( int i = 0; i < 3; ++i )
1208 {
1209 if( NextTok() != T_NUMBER )
1210 Expecting( T_NUMBER );
1211
1212 growth->vertex[i].x = strtod( CurText(), 0 );
1213
1214 if( NextTok() != T_NUMBER )
1215 Expecting( T_NUMBER );
1216
1217 growth->vertex[i].y = strtod( CurText(), 0 );
1218 }
1219
1220 NeedRIGHT();
1221}

References DSN::QARC::aperture_width, DSN::QARC::layer_id, DSN::QARC::vertex, DSN::POINT::x, and DSN::POINT::y.

Referenced by doKEEPOUT(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doRECTANGLE()

void DSN::SPECCTRA_DB::doRECTANGLE ( RECTANGLE growth)
private

Definition at line 1137 of file specctra.cpp.

1138{
1139 NeedSYMBOL();
1140 growth->layer_id = CurText();
1141
1142 if( NextTok() != T_NUMBER )
1143 Expecting( T_NUMBER );
1144
1145 growth->point0.x = strtod( CurText(), nullptr );
1146
1147 if( NextTok() != T_NUMBER )
1148 Expecting( T_NUMBER );
1149
1150 growth->point0.y = strtod( CurText(), nullptr );
1151
1152 if( NextTok() != T_NUMBER )
1153 Expecting( T_NUMBER );
1154
1155 growth->point1.x = strtod( CurText(), nullptr );
1156
1157 if( NextTok() != T_NUMBER )
1158 Expecting( T_NUMBER );
1159
1160 growth->point1.y = strtod( CurText(), nullptr );
1161
1162 NeedRIGHT();
1163}

References DSN::RECTANGLE::layer_id, DSN::RECTANGLE::point0, DSN::RECTANGLE::point1, DSN::POINT::x, and DSN::POINT::y.

Referenced by doBOUNDARY(), doKEEPOUT(), doREGION(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doREGION()

void DSN::SPECCTRA_DB::doREGION ( REGION growth)
private

Definition at line 1627 of file specctra.cpp.

1628{
1629 T tok = NextTok();
1630
1631 if( IsSymbol( tok ) )
1632 {
1633 growth->region_id = CurText();
1634 tok = NextTok();
1635 }
1636
1637 for(;;)
1638 {
1639 if( tok != T_LEFT )
1640 Expecting( T_LEFT );
1641
1642 tok = NextTok();
1643
1644 switch( tok )
1645 {
1646 case T_rect:
1647 if( growth->rectangle )
1648 Unexpected( tok );
1649
1650 growth->rectangle = new RECTANGLE( growth );
1651 doRECTANGLE( growth->rectangle );
1652 break;
1653
1654 case T_polygon:
1655 if( growth->polygon )
1656 Unexpected( tok );
1657
1658 growth->polygon = new PATH( growth, T_polygon );
1659 doPATH( growth->polygon );
1660 break;
1661
1662 case T_region_net:
1663 case T_region_class:
1664 STRINGPROP* stringprop;
1665 stringprop = new STRINGPROP( growth, tok );
1666 growth->Append( stringprop );
1667 doSTRINGPROP( stringprop );
1668 break;
1669
1670 case T_region_class_class:
1671 CLASS_CLASS* class_class;
1672 class_class = new CLASS_CLASS( growth, tok );
1673 growth->Append( class_class );
1674 doCLASS_CLASS( class_class );
1675 break;
1676
1677 case T_rule:
1678 if( growth->rules )
1679 Unexpected( tok );
1680
1681 growth->rules = new RULE( growth, T_rule );
1682 doRULE( growth->rules );
1683 break;
1684
1685 default:
1686 Unexpected( CurText() );
1687 }
1688
1689 tok = NextTok();
1690
1691 if( tok == T_RIGHT )
1692 {
1693 if( !growth->rules )
1694 Expecting( T_rule );
1695
1696 break;
1697 }
1698 }
1699}
void doCLASS_CLASS(CLASS_CLASS *growth)
Definition: specctra.cpp:1702
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1224

References DSN::ELEM_HOLDER::Append(), doCLASS_CLASS(), doPATH(), doRECTANGLE(), doRULE(), doSTRINGPROP(), DSN::REGION::polygon, RECTANGLE, DSN::REGION::rectangle, DSN::REGION::region_id, RULE, and DSN::REGION::rules.

Referenced by doPLACE(), and doSTRUCTURE().

◆ doRESOLUTION()

void DSN::SPECCTRA_DB::doRESOLUTION ( UNIT_RES growth)
private

Definition at line 567 of file specctra.cpp.

568{
569 T tok = NextTok();
570
571 switch( tok )
572 {
573 case T_inch:
574 case T_mil:
575 case T_cm:
576 case T_mm:
577 case T_um:
578 growth->units = tok;
579 break;
580 default:
581 Expecting( "inch|mil|cm|mm|um" );
582 }
583
584 tok = NextTok();
585
586 if( tok != T_NUMBER )
587 Expecting( T_NUMBER );
588
589 growth->value = atoi( CurText() );
590
591 NeedRIGHT();
592}

References DSN::UNIT_RES::units, and DSN::UNIT_RES::value.

Referenced by doPCB(), doPLACEMENT(), doROUTE(), doSTRUCTURE(), and doWIRING().

◆ doROUTE()

void DSN::SPECCTRA_DB::doROUTE ( ROUTE growth)
private

Definition at line 3497 of file specctra.cpp.

3498{
3499 T tok;
3500
3501 /* <route_descriptor >::=
3502 (routes
3503 <resolution_descriptor>
3504 <parser_descriptor>
3505 <structure_out_descriptor>
3506 <library_out_descriptor>
3507 <network_out_descriptor>
3508 <test_points_descriptor>
3509 )
3510 */
3511
3512 while( ( tok = NextTok() ) != T_RIGHT )
3513 {
3514 if( tok != T_LEFT )
3515 Expecting( T_LEFT );
3516
3517 tok = NextTok();
3518
3519 switch( tok )
3520 {
3521 case T_resolution:
3522 if( growth->resolution )
3523 Unexpected( tok );
3524
3525 growth->resolution = new UNIT_RES( growth, tok );
3526 doRESOLUTION( growth->resolution );
3527 break;
3528
3529 case T_parser:
3530 if( growth->parser )
3531 {
3532#if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
3533 // Work around their bug for now.
3534 Unexpected( tok );
3535#else
3536 delete growth->parser;
3537#endif
3538 }
3539
3540 growth->parser = new PARSER( growth );
3541 doPARSER( growth->parser );
3542 break;
3543
3544 case T_structure_out:
3545 if( growth->structure_out )
3546 Unexpected( tok );
3547
3548 growth->structure_out = new STRUCTURE_OUT( growth );
3549 doSTRUCTURE_OUT( growth->structure_out );
3550 break;
3551
3552 case T_library_out:
3553 if( growth->library )
3554 Unexpected( tok );
3555
3556 growth->library = new LIBRARY( growth, tok );
3557 doLIBRARY( growth->library );
3558 break;
3559
3560 case T_network_out:
3561 while( ( tok = NextTok() ) != T_RIGHT )
3562 {
3563 if( tok != T_LEFT )
3564 Expecting( T_LEFT );
3565
3566 tok = NextTok();
3567
3568 if( tok != T_net ) // it is class NET_OUT, but token T_net
3569 Unexpected( CurText() );
3570
3571 NET_OUT* net_out;
3572 net_out = new NET_OUT( growth );
3573
3574 growth->net_outs.push_back( net_out );
3575 doNET_OUT( net_out );
3576 }
3577
3578 break;
3579
3580 default:
3581 Unexpected( CurText() );
3582 }
3583 }
3584}
void doNET_OUT(NET_OUT *growth)
Definition: specctra.cpp:3587
void doSTRUCTURE_OUT(STRUCTURE_OUT *growth)
Definition: specctra.cpp:798

References doLIBRARY(), doNET_OUT(), doPARSER(), doRESOLUTION(), doSTRUCTURE_OUT(), DSN::ROUTE::library, DSN::ROUTE::net_outs, DSN::ROUTE::parser, DSN::ROUTE::resolution, and DSN::ROUTE::structure_out.

Referenced by doSESSION().

◆ doRULE()

void DSN::SPECCTRA_DB::doRULE ( RULE growth)
private

Definition at line 1489 of file specctra.cpp.

1490{
1491 std::string builder;
1492 int bracketNesting = 1; // we already saw the opening T_LEFT
1493 T tok = T_NONE;
1494
1495 while( bracketNesting != 0 && tok != T_EOF )
1496 {
1497 tok = NextTok();
1498
1499 if( tok==T_LEFT)
1500 ++bracketNesting;
1501 else if( tok==T_RIGHT )
1502 --bracketNesting;
1503
1504 if( bracketNesting >= 1 )
1505 {
1506 if( PrevTok() != T_LEFT && tok != T_RIGHT && ( tok != T_LEFT || bracketNesting > 2 ) )
1507 builder += ' ';
1508
1509 if( tok == T_STRING )
1510 builder += m_quote_char;
1511
1512 builder += CurText();
1513
1514 if( tok == T_STRING )
1515 builder += m_quote_char;
1516 }
1517
1518 // When the nested rule is closed with a T_RIGHT and we are back down
1519 // to bracketNesting == 1, (inside the <rule_descriptor> but outside
1520 // the last rule). Then save the last rule and clear the string builder.
1521 if( bracketNesting == 1 )
1522 {
1523 growth->rules.push_back( builder );
1524 builder.clear();
1525 }
1526 }
1527
1528 if( tok==T_EOF )
1529 Unexpected( T_EOF );
1530}

References m_quote_char, and DSN::RULE::rules.

Referenced by doCLASS(), doCLASS_CLASS(), doFROMTO(), doIMAGE(), doKEEPOUT(), doLAYER(), doLAYER_RULE(), doNET(), doNET_OUT(), doPADSTACK(), doPLACE(), doREGION(), doSTRUCTURE(), and doSTRUCTURE_OUT().

◆ doSESSION()

void DSN::SPECCTRA_DB::doSESSION ( SESSION growth)
private

Definition at line 3373 of file specctra.cpp.

3374{
3375 T tok;
3376
3377 /* <session_file_descriptor >::=
3378 (session <session_id >
3379 (base_design <path/filename >)
3380 [<history_descriptor> ]
3381 [<session_structure_descriptor> ]
3382 [<placement_descriptor> ]
3383 [<floor_plan_descriptor> ]
3384 [<net_pin_changes_descriptor> ]
3385 [<was_is_descriptor> ]
3386 <swap_history_descriptor> ]
3387 [<route_descriptor> ]
3388 )
3389 */
3390
3391 NeedSYMBOL();
3392 growth->session_id = CurText();
3393
3394 while( ( tok = NextTok() ) != T_RIGHT )
3395 {
3396 if( tok != T_LEFT )
3397 Expecting( T_LEFT );
3398
3399 tok = NextTok();
3400
3401 switch( tok )
3402 {
3403 case T_base_design:
3404 NeedSYMBOL();
3405 growth->base_design = CurText();
3406 NeedRIGHT();
3407 break;
3408
3409 case T_history:
3410 if( growth->history )
3411 Unexpected( tok );
3412
3413 growth->history = new HISTORY( growth );
3414 doHISTORY( growth->history );
3415 break;
3416
3417 case T_structure:
3418 if( growth->structure )
3419 Unexpected( tok );
3420
3421 growth->structure = new STRUCTURE( growth );
3422 doSTRUCTURE( growth->structure );
3423 break;
3424
3425 case T_placement:
3426 if( growth->placement )
3427 Unexpected( tok );
3428
3429 growth->placement = new PLACEMENT( growth );
3430 doPLACEMENT( growth->placement );
3431 break;
3432
3433 case T_was_is:
3434 if( growth->was_is )
3435 Unexpected( tok );
3436
3437 growth->was_is = new WAS_IS( growth );
3438 doWAS_IS( growth->was_is );
3439 break;
3440
3441 case T_routes:
3442 if( growth->route )
3443 Unexpected( tok );
3444
3445 growth->route = new ROUTE( growth );
3446 doROUTE( growth->route );
3447 break;
3448
3449 default:
3450 Unexpected( CurText() );
3451 }
3452 }
3453}
void doWAS_IS(WAS_IS *growth)
Definition: specctra.cpp:3456
void doROUTE(ROUTE *growth)
Definition: specctra.cpp:3497
void doHISTORY(HISTORY *growth)
Definition: specctra.cpp:3314

References DSN::SESSION::base_design, doHISTORY(), doPLACEMENT(), doROUTE(), doSTRUCTURE(), doWAS_IS(), DSN::SESSION::history, DSN::SESSION::placement, DSN::SESSION::route, DSN::SESSION::session_id, DSN::SESSION::structure, and DSN::SESSION::was_is.

Referenced by LoadSESSION().

◆ doSHAPE()

void DSN::SPECCTRA_DB::doSHAPE ( SHAPE growth)
private

Definition at line 2213 of file specctra.cpp.

2214{
2215 T tok;
2216
2217 /* (shape <shape_descriptor>
2218 [<reduced_shape_descriptor> ]
2219 [(connect [on | off])]
2220 [{<window_descriptor> }])
2221 */
2222
2223 while( ( tok = NextTok() ) != T_RIGHT )
2224 {
2225 if( tok != T_LEFT )
2226 Expecting( T_LEFT );
2227
2228 tok = NextTok();
2229
2230 switch( tok )
2231 {
2232 case T_polyline_path:
2233 tok = T_path;
2235
2236 case T_rect:
2237 case T_circle:
2238 case T_path:
2239 case T_polygon:
2240 case T_qarc:
2241L_done_that:
2242 if( growth->shape )
2243 Unexpected( tok );
2244
2245 break;
2246
2247 default:
2248 // the example in the spec uses "circ" instead of "circle". Bad!
2249 if( !strcmp( "circ", CurText() ) )
2250 {
2251 tok = T_circle;
2252 goto L_done_that;
2253 }
2254 }
2255
2256 switch( tok )
2257 {
2258 case T_rect:
2259 growth->shape = new RECTANGLE( growth );
2260 doRECTANGLE( (RECTANGLE*) growth->shape );
2261 break;
2262
2263 case T_circle:
2264 growth->shape = new CIRCLE( growth );
2265 doCIRCLE( (CIRCLE*)growth->shape );
2266 break;
2267
2268 case T_path:
2269 case T_polygon:
2270 growth->shape = new PATH( growth, tok );
2271 doPATH( (PATH*)growth->shape );
2272 break;
2273
2274 case T_qarc:
2275 growth->shape = new QARC( growth );
2276 doQARC( (QARC*)growth->shape );
2277 break;
2278
2279 case T_connect:
2280 tok = NextTok();
2281 if( tok!=T_on && tok!=T_off )
2282 Expecting( "on|off" );
2283 growth->connect = tok;
2284 NeedRIGHT();
2285 break;
2286
2287 case T_window:
2288 WINDOW* window;
2289 window = new WINDOW( growth );
2290 growth->windows.push_back( window );
2291 doWINDOW( window );
2292 break;
2293
2294 default:
2295 Unexpected( CurText() );
2296 }
2297 }
2298}

References CIRCLE, DSN::SHAPE::connect, doCIRCLE(), doPATH(), doQARC(), doRECTANGLE(), doWINDOW(), KI_FALLTHROUGH, RECTANGLE, DSN::WINDOW::shape, and DSN::SHAPE::windows.

Referenced by doIMAGE(), and doPADSTACK().

◆ doSPECCTRA_LAYER_PAIR()

void DSN::SPECCTRA_DB::doSPECCTRA_LAYER_PAIR ( SPECCTRA_LAYER_PAIR growth)
private

Definition at line 616 of file specctra.cpp.

617{
618 NeedSYMBOL();
619 growth->layer_id0 = CurText();
620
621 NeedSYMBOL();
622 growth->layer_id1 = CurText();
623
624 if( NextTok() != T_NUMBER )
625 Expecting( T_NUMBER );
626
627 growth->layer_weight = strtod( CurText(), 0 );
628
629 NeedRIGHT();
630}

References DSN::SPECCTRA_LAYER_PAIR::layer_id0, DSN::SPECCTRA_LAYER_PAIR::layer_id1, and DSN::SPECCTRA_LAYER_PAIR::layer_weight.

Referenced by doLAYER_NOISE_WEIGHT().

◆ doSTRINGPROP()

void DSN::SPECCTRA_DB::doSTRINGPROP ( STRINGPROP growth)
private

Definition at line 1224 of file specctra.cpp.

1225{
1226 NeedSYMBOL();
1227 growth->value = CurText();
1228 NeedRIGHT();
1229}

References DSN::STRINGPROP::value.

Referenced by doREGION(), and doSTRUCTURE().

◆ doSTRUCTURE()

void DSN::SPECCTRA_DB::doSTRUCTURE ( STRUCTURE growth)
private

Definition at line 653 of file specctra.cpp.

654{
655 T tok;
656
657 while( ( tok = NextTok() ) != T_RIGHT )
658 {
659 if( tok != T_LEFT )
660 Expecting( T_LEFT );
661
662 tok = NextTok();
663
664 switch( tok )
665 {
666 case T_unit:
667 if( growth->unit )
668 Unexpected( tok );
669
670 growth->unit = new UNIT_RES( growth, tok );
671 doUNIT( growth->unit );
672 break;
673
674 case T_resolution:
675 if( growth->unit )
676 Unexpected( tok );
677
678 growth->unit = new UNIT_RES( growth, tok );
679 doRESOLUTION( growth->unit );
680 break;
681
682 case T_layer_noise_weight:
683 if( growth->layer_noise_weight )
684 Unexpected( tok );
685
686 growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
687 doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
688 break;
689
690 case T_place_boundary:
691L_place:
692 if( growth->place_boundary )
693 Unexpected( tok );
694
695 growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
696 doBOUNDARY( growth->place_boundary );
697 break;
698
699 case T_boundary:
700 if( growth->boundary )
701 {
702 if( growth->place_boundary )
703 Unexpected( tok );
704
705 goto L_place;
706 }
707
708 growth->boundary = new BOUNDARY( growth );
709 doBOUNDARY( growth->boundary );
710 break;
711
712 case T_plane:
713 COPPER_PLANE* plane;
714 plane = new COPPER_PLANE( growth );
715 growth->planes.push_back( plane );
716 doKEEPOUT( plane );
717 break;
718
719 case T_region:
720 REGION* region;
721 region = new REGION( growth );
722 growth->regions.push_back( region );
723 doREGION( region );
724 break;
725
726 case T_snap_angle:
727 STRINGPROP* stringprop;
728 stringprop = new STRINGPROP( growth, T_snap_angle );
729 growth->Append( stringprop );
730 doSTRINGPROP( stringprop );
731 break;
732
733 case T_via:
734 if( growth->via )
735 Unexpected( tok );
736
737 growth->via = new VIA( growth );
738 doVIA( growth->via );
739 break;
740
741 case T_control:
742 if( growth->control )
743 Unexpected( tok );
744
745 growth->control = new CONTROL( growth );
746 doCONTROL( growth->control );
747 break;
748
749 case T_layer:
750 LAYER* layer;
751 layer = new LAYER( growth );
752 growth->layers.push_back( layer );
753 doLAYER( layer );
754 break;
755
756 case T_rule:
757 if( growth->rules )
758 Unexpected( tok );
759
760 growth->rules = new RULE( growth, T_rule );
761 doRULE( growth->rules );
762 break;
763
764 case T_place_rule:
765 if( growth->place_rules )
766 Unexpected( tok );
767
768 growth->place_rules = new RULE( growth, T_place_rule );
769 doRULE( growth->place_rules );
770 break;
771
772 case T_keepout:
773 case T_place_keepout:
774 case T_via_keepout:
775 case T_wire_keepout:
776 case T_bend_keepout:
777 case T_elongate_keepout:
778 KEEPOUT* keepout;
779 keepout = new KEEPOUT( growth, tok );
780 growth->keepouts.push_back( keepout );
781 doKEEPOUT( keepout );
782 break;
783
784 case T_grid:
785 GRID* grid;
786 grid = new GRID( growth );
787 growth->grids.push_back( grid );
788 doGRID( grid );
789 break;
790
791 default:
792 Unexpected( CurText() );
793 }
794 }
795}
void doLAYER_NOISE_WEIGHT(LAYER_NOISE_WEIGHT *growth)
Definition: specctra.cpp:633
void doBOUNDARY(BOUNDARY *growth)
Definition: specctra.cpp:1036
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1349
void doVIA(VIA *growth)
Definition: specctra.cpp:1245
void doGRID(GRID *growth)
Definition: specctra.cpp:1774
void doCONTROL(CONTROL *growth)
Definition: specctra.cpp:1276
@ VIA
Normal via.
Definition: router_tool.cpp:82
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:156

References DSN::ELEM_HOLDER::Append(), DSN::STRUCTURE::boundary, DSN::STRUCTURE::control, doBOUNDARY(), doCONTROL(), doGRID(), doKEEPOUT(), doLAYER(), doLAYER_NOISE_WEIGHT(), doREGION(), doRESOLUTION(), doRULE(), doSTRINGPROP(), doUNIT(), doVIA(), grid, DSN::STRUCTURE::grids, DSN::STRUCTURE::keepouts, DSN::STRUCTURE::layer_noise_weight, DSN::STRUCTURE::layers, DSN::STRUCTURE::place_boundary, DSN::STRUCTURE::place_rules, DSN::STRUCTURE::planes, REGION, DSN::STRUCTURE::regions, RULE, DSN::STRUCTURE::rules, DSN::STRUCTURE::unit, VIA, and DSN::STRUCTURE::via.

Referenced by doPCB(), and doSESSION().

◆ doSTRUCTURE_OUT()

void DSN::SPECCTRA_DB::doSTRUCTURE_OUT ( STRUCTURE_OUT growth)
private

Definition at line 798 of file specctra.cpp.

799{
800 /*
801 <structure_out_descriptor >::=
802 (structure_out
803 {<layer_descriptor> }
804 [<rule_descriptor> ]
805 )
806 */
807
808 T tok = NextTok();
809
810 while( tok != T_RIGHT )
811 {
812 if( tok != T_LEFT )
813 Expecting( T_LEFT );
814
815 tok = NextTok();
816
817 switch( tok )
818 {
819 case T_layer:
820 LAYER* layer;
821 layer = new LAYER( growth );
822 growth->layers.push_back( layer );
823 doLAYER( layer );
824 break;
825
826 case T_rule:
827 if( growth->rules )
828 Unexpected( tok );
829
830 growth->rules = new RULE( growth, T_rule );
831 doRULE( growth->rules );
832 break;
833
834 default:
835 Unexpected( CurText() );
836 }
837
838 tok = NextTok();
839 }
840}

References doLAYER(), doRULE(), DSN::STRUCTURE_OUT::layers, RULE, and DSN::STRUCTURE_OUT::rules.

Referenced by doROUTE().

◆ doSUPPLY_PIN()

void DSN::SPECCTRA_DB::doSUPPLY_PIN ( SUPPLY_PIN growth)
private

Definition at line 3659 of file specctra.cpp.

3660{
3661 T tok;
3662 PIN_REF empty(growth);
3663
3664 /* <supply_pin_descriptor >::=
3665 (supply_pin {<pin_reference> } [(net <net_id >)])
3666 */
3667
3668 NeedSYMBOL();
3669 growth->net_id = CurText();
3670
3671 while( ( tok = NextTok() ) != T_RIGHT )
3672 {
3673 if( IsSymbol(tok) )
3674 {
3675 growth->pin_refs.push_back( empty );
3676
3677 PIN_REF* pin_ref = &growth->pin_refs.back();
3678
3679 readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
3680 }
3681 else if( tok == T_LEFT )
3682 {
3683 tok = NextTok();
3684
3685 if( tok != T_net )
3686 Expecting( T_net );
3687
3688 growth->net_id = CurText();
3689 NeedRIGHT();
3690 }
3691 else
3692 Unexpected( CurText() );
3693 }
3694}

References DSN::PIN_REF::component_id, empty(), DSN::SUPPLY_PIN::net_id, DSN::PIN_REF::pin_id, DSN::SUPPLY_PIN::pin_refs, and readCOMPnPIN().

Referenced by doNET_OUT().

◆ doTOKPROP()

void DSN::SPECCTRA_DB::doTOKPROP ( TOKPROP growth)
private

Definition at line 1232 of file specctra.cpp.

1233{
1234 T tok = NextTok();
1235
1236 if( tok<0 )
1237 Unexpected( CurText() );
1238
1239 growth->value = tok;
1240
1241 NeedRIGHT();
1242}

References DSN::TOKPROP::value.

Referenced by doCONTROL().

◆ doTOPOLOGY()

void DSN::SPECCTRA_DB::doTOPOLOGY ( TOPOLOGY growth)
private

Definition at line 2658 of file specctra.cpp.

2659{
2660 T tok;
2661
2662 /* <topology_descriptor >::=
2663 (topology {[<fromto_descriptor> |
2664 <component_order_descriptor> ]})
2665 */
2666
2667 while( ( tok = NextTok() ) != T_RIGHT )
2668 {
2669 if( tok != T_LEFT )
2670 Expecting( T_LEFT );
2671
2672 tok = NextTok();
2673
2674 switch( tok )
2675 {
2676 case T_fromto:
2677 FROMTO* fromto;
2678 fromto = new FROMTO( growth );
2679 growth->fromtos.push_back( fromto );
2680 doFROMTO( fromto );
2681 break;
2682
2683 case T_comp_order:
2684 COMP_ORDER* comp_order;
2685 comp_order = new COMP_ORDER( growth );
2686 growth->comp_orders.push_back( comp_order );
2687 doCOMP_ORDER( comp_order );
2688 break;
2689
2690 default:
2691 Unexpected( CurText() );
2692 }
2693 }
2694}

References DSN::TOPOLOGY::comp_orders, doCOMP_ORDER(), doFROMTO(), and DSN::TOPOLOGY::fromtos.

Referenced by doCLASS().

◆ doUNIT()

void DSN::SPECCTRA_DB::doUNIT ( UNIT_RES growth)
private

Definition at line 595 of file specctra.cpp.

596{
597 T tok = NextTok();
598
599 switch( tok )
600 {
601 case T_inch:
602 case T_mil:
603 case T_cm:
604 case T_mm:
605 case T_um:
606 growth->units = tok;
607 break;
608 default:
609 Expecting( "inch|mil|cm|mm|um" );
610 }
611
612 NeedRIGHT();
613}

References DSN::UNIT_RES::units.

Referenced by doIMAGE(), doLIBRARY(), doPADSTACK(), doPCB(), doPLACEMENT(), doSTRUCTURE(), and doWIRING().

◆ doVIA()

void DSN::SPECCTRA_DB::doVIA ( VIA growth)
private

Definition at line 1245 of file specctra.cpp.

1246{
1247 T tok;
1248
1249 while( ( tok = NextTok() ) != T_RIGHT )
1250 {
1251 if( tok == T_LEFT )
1252 {
1253 if( NextTok() != T_spare )
1254 Expecting( T_spare );
1255
1256 while( (tok = NextTok()) != T_RIGHT )
1257 {
1258 if( !IsSymbol( tok ) )
1259 Expecting( T_SYMBOL );
1260
1261 growth->spares.push_back( CurText() );
1262 }
1263 }
1264 else if( IsSymbol( tok ) )
1265 {
1266 growth->padstacks.push_back( CurText() );
1267 }
1268 else
1269 {
1270 Unexpected( CurText() );
1271 }
1272 }
1273}

References DSN::VIA::padstacks, and DSN::VIA::spares.

Referenced by doSTRUCTURE().

◆ doWAS_IS()

void DSN::SPECCTRA_DB::doWAS_IS ( WAS_IS growth)
private

Definition at line 3456 of file specctra.cpp.

3457{
3458 T tok;
3459 PIN_PAIR empty( growth );
3460 PIN_PAIR* pin_pair;
3461
3462 /* <was_is_descriptor >::=
3463 (was_is {(pins <pin_reference> <pin_reference> )})
3464 */
3465
3466 // none of the pins is ok too
3467 while( ( tok = NextTok() ) != T_RIGHT )
3468 {
3469 if( tok != T_LEFT )
3470 Expecting( T_LEFT );
3471
3472 tok = NextTok();
3473
3474 switch( tok )
3475 {
3476 case T_pins:
3477 // copy the empty one, then fill its copy later thru pin_pair.
3478 growth->pin_pairs.push_back( empty );
3479 pin_pair= &growth->pin_pairs.back();
3480
3481 NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3482 readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
3483
3484 NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3485 readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
3486
3487 NeedRIGHT();
3488 break;
3489
3490 default:
3491 Unexpected( CurText() );
3492 }
3493 }
3494}

References DSN::PIN_REF::component_id, empty(), DSN::PIN_PAIR::is, DSN::PIN_REF::pin_id, DSN::WAS_IS::pin_pairs, readCOMPnPIN(), and DSN::PIN_PAIR::was.

Referenced by doSESSION().

◆ doWINDOW()

void DSN::SPECCTRA_DB::doWINDOW ( WINDOW growth)
private

Definition at line 977 of file specctra.cpp.

978{
979 T tok = NextTok();
980
981 while( tok != T_RIGHT )
982 {
983 if( tok!=T_LEFT )
984 Expecting( T_LEFT );
985
986 tok = NextTok();
987
988 switch( tok )
989 {
990 case T_rect:
991 if( growth->shape )
992 Unexpected( tok );
993
994 growth->shape = new RECTANGLE( growth );
995 doRECTANGLE( (RECTANGLE*) growth->shape );
996 break;
997
998 case T_circle:
999 if( growth->shape )
1000 Unexpected( tok );
1001
1002 growth->shape = new CIRCLE( growth );
1003 doCIRCLE( (CIRCLE*) growth->shape );
1004 break;
1005
1006 case T_polyline_path:
1007 tok = T_path;
1009
1010 case T_path:
1011 case T_polygon:
1012 if( growth->shape )
1013 Unexpected( tok );
1014
1015 growth->shape = new PATH( growth, tok );
1016 doPATH( (PATH*) growth->shape );
1017 break;
1018
1019 case T_qarc:
1020 if( growth->shape )
1021 Unexpected( tok );
1022
1023 growth->shape = new QARC( growth );
1024 doQARC( (QARC*) growth->shape );
1025 break;
1026
1027 default:
1028 Unexpected( CurText() );
1029 }
1030
1031 tok = NextTok();
1032 }
1033}

References CIRCLE, doCIRCLE(), doPATH(), doQARC(), doRECTANGLE(), KI_FALLTHROUGH, RECTANGLE, and DSN::WINDOW::shape.

Referenced by doKEEPOUT(), doSHAPE(), and doWIRE().

◆ doWIRE()

void DSN::SPECCTRA_DB::doWIRE ( WIRE growth)
private

Definition at line 2967 of file specctra.cpp.

2968{
2969 T tok;
2970
2971 /* <wire_shape_descriptor >::=
2972 (wire
2973 <shape_descriptor>
2974 [(net <net_id >)]
2975 [(turret <turret#> )]
2976 [(type [fix | route | normal | protect])]
2977 [(attr [test | fanout | bus | jumper])]
2978 [(shield <net_id >)]
2979 [{<window_descriptor> }]
2980 [(connect
2981 (terminal <object_type> [<pin_reference> ])
2982 (terminal <object_type> [<pin_reference> ])
2983 )]
2984 [(supply)]
2985 )
2986 */
2987
2988 while( ( tok = NextTok() ) != T_RIGHT )
2989 {
2990 if( tok != T_LEFT )
2991 Expecting( T_LEFT );
2992
2993 tok = NextTok();
2994
2995 switch( tok )
2996 {
2997 case T_rect:
2998 if( growth->shape )
2999 Unexpected( tok );
3000
3001 growth->shape = new RECTANGLE( growth );
3002 doRECTANGLE( (RECTANGLE*) growth->shape );
3003 break;
3004
3005 case T_circle:
3006 if( growth->shape )
3007 Unexpected( tok );
3008
3009 growth->shape = new CIRCLE( growth );
3010 doCIRCLE( (CIRCLE*) growth->shape );
3011 break;
3012
3013 case T_polyline_path:
3014 tok = T_path;
3016
3017 case T_path:
3018 case T_polygon:
3019 if( growth->shape )
3020 Unexpected( tok );
3021
3022 growth->shape = new PATH( growth, tok );
3023 doPATH( (PATH*) growth->shape );
3024 break;
3025
3026 case T_qarc:
3027 if( growth->shape )
3028 Unexpected( tok );
3029
3030 growth->shape = new QARC( growth );
3031 doQARC( (QARC*) growth->shape );
3032 break;
3033
3034 case T_net:
3035 NeedSYMBOLorNUMBER();
3036 growth->net_id = CurText();
3037 NeedRIGHT();
3038 break;
3039
3040 case T_turret:
3041 if( NextTok() != T_NUMBER )
3042 Expecting( T_NUMBER );
3043
3044 growth->turret = atoi( CurText() );
3045 NeedRIGHT();
3046 break;
3047
3048 case T_type:
3049 tok = NextTok();
3050
3051 if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3052 Expecting( "fix|route|normal|protect" );
3053
3054 growth->wire_type = tok;
3055 NeedRIGHT();
3056 break;
3057
3058 case T_attr:
3059 tok = NextTok();
3060
3061 if( tok != T_test && tok != T_fanout && tok != T_bus && tok != T_jumper )
3062 Expecting( "test|fanout|bus|jumper" );
3063
3064 growth->attr = tok;
3065 NeedRIGHT();
3066 break;
3067
3068 case T_shield:
3069 NeedSYMBOL();
3070 growth->shield = CurText();
3071 NeedRIGHT();
3072 break;
3073
3074 case T_window:
3075 WINDOW* window;
3076 window = new WINDOW( growth );
3077 growth->windows.push_back( window );
3078 doWINDOW( window );
3079 break;
3080
3081 case T_connect:
3082 if( growth->connect )
3083 Unexpected( tok );
3084
3085 growth->connect = new CONNECT( growth );
3086 doCONNECT( growth->connect );
3087 break;
3088
3089 case T_supply:
3090 growth->supply = true;
3091 NeedRIGHT();
3092 break;
3093
3094 default:
3095 Unexpected( CurText() );
3096 }
3097 }
3098}
void doCONNECT(CONNECT *growth)
Definition: specctra.cpp:942

References DSN::WIRE::attr, CIRCLE, DSN::WIRE::connect, doCIRCLE(), doCONNECT(), doPATH(), doQARC(), doRECTANGLE(), doWINDOW(), KI_FALLTHROUGH, DSN::WIRE::net_id, RECTANGLE, DSN::WIRE::shape, DSN::WIRE::shield, DSN::WIRE::supply, DSN::WIRE::turret, DSN::WIRE::windows, and DSN::WIRE::wire_type.

Referenced by doNET_OUT(), and doWIRING().

◆ doWIRE_VIA()

void DSN::SPECCTRA_DB::doWIRE_VIA ( WIRE_VIA growth)
private

Definition at line 3101 of file specctra.cpp.

3102{
3103 T tok;
3104 POINT point;
3105
3106 /* <wire_via_descriptor >::=
3107 (via
3108 <padstack_id > {<vertex> }
3109 [(net <net_id >)]
3110 [(via_number <via#> )]
3111 [(type [fix | route | normal | protect])]
3112 [(attr [test | fanout | jumper |
3113 virtual_pin <virtual_pin_name> ])]
3114 [(contact {<layer_id >})]
3115 [(supply)]
3116 )
3117 (virtual_pin
3118 <virtual_pin_name> <vertex> (net <net_id >)
3119 )
3120 */
3121
3122 NeedSYMBOL();
3123 growth->padstack_id = CurText();
3124
3125 while( ( tok = NextTok() ) == T_NUMBER )
3126 {
3127 point.x = strtod( CurText(), 0 );
3128
3129 if( NextTok() != T_NUMBER )
3130 Expecting( "vertex.y" );
3131
3132 point.y = strtod( CurText(), 0 );
3133
3134 growth->vertexes.push_back( point );
3135 }
3136
3137 while( tok != T_RIGHT )
3138 {
3139 if( tok != T_LEFT )
3140 Expecting( T_LEFT );
3141
3142 tok = NextTok();
3143
3144 switch( tok )
3145 {
3146 case T_net:
3147 NeedSYMBOL();
3148 growth->net_id = CurText();
3149 NeedRIGHT();
3150 break;
3151
3152 case T_via_number:
3153 if( NextTok() != T_NUMBER )
3154 Expecting( "<via#>" );
3155
3156 growth->via_number = atoi( CurText() );
3157 NeedRIGHT();
3158 break;
3159
3160 case T_type:
3161 tok = NextTok();
3162
3163 if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3164 Expecting( "fix|route|normal|protect" );
3165
3166 growth->via_type = tok;
3167 NeedRIGHT();
3168 break;
3169
3170 case T_attr:
3171 tok = NextTok();
3172
3173 if( tok != T_test && tok != T_fanout && tok != T_jumper && tok != T_virtual_pin )
3174 Expecting( "test|fanout|jumper|virtual_pin" );
3175
3176 growth->attr = tok;
3177
3178 if( tok == T_virtual_pin )
3179 {
3180 NeedSYMBOL();
3181 growth->virtual_pin_name = CurText();
3182 }
3183
3184 NeedRIGHT();
3185 break;
3186
3187 case T_contact:
3188 NeedSYMBOL();
3189 tok = T_SYMBOL;
3190
3191 while( IsSymbol( tok ) )
3192 {
3193 growth->contact_layers.push_back( CurText() );
3194 tok = NextTok();
3195 }
3196
3197 if( tok != T_RIGHT )
3198 Expecting( T_RIGHT );
3199
3200 break;
3201
3202 case T_supply:
3203 growth->supply = true;
3204 NeedRIGHT();
3205 break;
3206
3207 default:
3208 Unexpected( CurText() );
3209 }
3210
3211 tok = NextTok();
3212 }
3213}

References DSN::WIRE_VIA::attr, DSN::WIRE_VIA::contact_layers, DSN::WIRE_VIA::net_id, DSN::WIRE_VIA::padstack_id, DSN::WIRE_VIA::supply, DSN::WIRE_VIA::vertexes, DSN::WIRE_VIA::via_number, DSN::WIRE_VIA::via_type, DSN::WIRE_VIA::virtual_pin_name, DSN::POINT::x, and DSN::POINT::y.

Referenced by doNET_OUT(), and doWIRING().

◆ doWIRING()

void DSN::SPECCTRA_DB::doWIRING ( WIRING growth)
private

Definition at line 3216 of file specctra.cpp.

3217{
3218 T tok;
3219
3220 /* <wiring_descriptor >::=
3221 (wiring
3222 [<unit_descriptor> | <resolution_descriptor> | null]
3223 {<wire_descriptor> }
3224 [<test_points_descriptor> ]
3225 {[<supply_pin_descriptor> ]}
3226 )
3227 */
3228
3229 while( ( tok = NextTok() ) != T_RIGHT )
3230 {
3231 if( tok != T_LEFT )
3232 Expecting( T_LEFT );
3233
3234 tok = NextTok();
3235
3236 switch( tok )
3237 {
3238 case T_unit:
3239 if( growth->unit )
3240 Unexpected( tok );
3241
3242 growth->unit = new UNIT_RES( growth, tok );
3243 doUNIT( growth->unit );
3244 break;
3245
3246 case T_resolution:
3247 if( growth->unit )
3248 Unexpected( tok );
3249
3250 growth->unit = new UNIT_RES( growth, tok );
3251 doRESOLUTION( growth->unit );
3252 break;
3253
3254 case T_wire:
3255 WIRE* wire;
3256 wire = new WIRE( growth );
3257 growth->wires.push_back( wire );
3258 doWIRE( wire );
3259 break;
3260
3261 case T_via:
3262 WIRE_VIA* wire_via;
3263 wire_via = new WIRE_VIA( growth );
3264 growth->wire_vias.push_back( wire_via );
3265 doWIRE_VIA( wire_via );
3266 break;
3267
3268 default:
3269 Unexpected( CurText() );
3270 }
3271 }
3272}

References doRESOLUTION(), doUNIT(), doWIRE(), doWIRE_VIA(), DSN::WIRING::unit, WIRE, DSN::WIRING::wire_vias, and DSN::WIRING::wires.

Referenced by doPCB().

◆ exportNETCLASS()

void DSN::SPECCTRA_DB::exportNETCLASS ( const std::shared_ptr< NETCLASS > &  aNetClass,
BOARD aBoard 
)
private

Export aNetClass to the DSN file.

Definition at line 1715 of file specctra_export.cpp.

1716{
1717 /* From page 11 of specctra spec:
1718 *
1719 * Routing and Placement Rule Hierarchies
1720 *
1721 * Routing and placement rules can be defined at multiple levels of design
1722 * specification. When a routing or placement rule is defined for an object at
1723 * multiple levels, a predefined routing or placement precedence order
1724 * automatically determines which rule to apply to the object. The routing rule
1725 * precedence order is
1726 *
1727 * pcb < layer < class < class layer < group_set < group_set layer < net <
1728 * net layer < group < group layer < fromto < fromto layer < class_class <
1729 * class_class layer < padstack < region < class region < net region <
1730 * class_class region
1731 *
1732 * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1733 * hierarchy. A class-to-class region rule has the highest precedence. Rules
1734 * set at one level of the hierarchy override conflicting rules set at lower
1735 * levels. The placement rule precedence order is
1736 *
1737 * pcb < image_set < image < component < super cluster < room <
1738 * room_image_set < family_family < image_image
1739 *
1740 * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1741 * hierarchy. An image-to-image rule has the highest precedence. Rules set at
1742 * one level of the hierarchy override conflicting rules set at lower levels.
1743 */
1744
1745 char text[256];
1746
1747 CLASS* clazz = new CLASS( m_pcb->network );
1748
1749 m_pcb->network->classes.push_back( clazz );
1750
1751 // Freerouter creates a class named 'default' anyway, and if we try to use that we end up
1752 // with two 'default' via rules so use something else as the name of our default class.
1753 clazz->class_id = TO_UTF8( aNetClass->GetName() );
1754
1755 for( NETINFO_ITEM* net : aBoard->GetNetInfo() )
1756 {
1757 if( net->GetNetClass()->GetName() == clazz->class_id )
1758 clazz->net_ids.push_back( TO_UTF8( net->GetNetname() ) );
1759 }
1760
1761 clazz->rules = new RULE( clazz, T_rule );
1762
1763 // output the track width.
1764 int trackWidth = aNetClass->GetTrackWidth();
1765 sprintf( text, "(width %.6g)", scale( trackWidth ) );
1766 clazz->rules->rules.push_back( text );
1767
1768 // output the clearance.
1769 int clearance = aNetClass->GetClearance();
1770 sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
1771 clazz->rules->rules.push_back( text );
1772
1773 if( aNetClass->GetName() == NETCLASS::Default )
1774 clazz->class_id = "kicad_default";
1775
1776 // The easiest way to get the via name is to create a temporary via (which generates the
1777 // name internal to the PADSTACK), and then grab the name and delete the via. There are not
1778 // that many netclasses so this should never become a performance issue.
1779
1780 PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(),
1782
1783 snprintf( text, sizeof(text), "(use_via %s)", via->GetPadstackId().c_str() );
1784 clazz->circuit.push_back( text );
1785
1786 delete via;
1787}
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:763
The <class_descriptor> in the specctra spec.
Definition: specctra.h:2754
RULE * rules
Definition: specctra.h:2832
std::string class_id
Definition: specctra.h:2825
STRINGS net_ids
Definition: specctra.h:2827
STRINGS circuit
circuit descriptor list
Definition: specctra.h:2830
CLASSLIST classes
Definition: specctra.h:2863
Hold either a via or a pad definition.
Definition: specctra.h:2127
NETWORK * network
Definition: specctra.h:3261
A <rule_descriptor> in the specctra dsn spec.
Definition: specctra.h:492
STRINGS rules
rules are saved in std::string form.
Definition: specctra.h:530
PADSTACK * makeVia(int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
Make a round through hole #PADSTACK using the given KiCad diameter in deci-mils.
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:49
Handle the data for a net.
Definition: netinfo.h:66
static double scale(int kicadDist)
Convert a distance from Pcbnew internal units to the reported Specctra DSN units in floating point fo...
static const double safetyMargin

References DSN::CLASS::circuit, DSN::CLASS::class_id, DSN::NETWORK::classes, NETCLASS::Default, BOARD::GetNetInfo(), m_bot_via_layer, m_pcb, m_top_via_layer, makeVia(), DSN::CLASS::net_ids, DSN::PCB::network, DSN::RULE::rules, DSN::CLASS::rules, safetyMargin, DSN::scale(), text, TO_UTF8, and via.

Referenced by FromBOARD().

◆ ExportPCB()

void DSN::SPECCTRA_DB::ExportPCB ( const wxString &  aFilename,
bool  aNameChange = false 
)

Write the internal PCB instance out as a SPECTRA DSN format file.

Parameters
aFilenameThe file to save to.
aNameChangeIf true, causes the pcb's name to change to "aFilename" and also to to be changed in the output file.
Exceptions
IO_ERROR,ifan i/o error occurs saving the file.

Definition at line 3697 of file specctra.cpp.

3698{
3699 if( m_pcb )
3700 {
3701 FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3702
3703 if( aNameChange )
3704 m_pcb->pcbname = TO_UTF8( aFilename );
3705
3706 m_pcb->Format( &formatter, 0 );
3707 }
3708}
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:3207
std::string pcbname
Definition: specctra.h:3254
Used for text file output.
Definition: richio.h:457

References DSN::PCB::Format(), m_pcb, m_quote_char, DSN::PCB::pcbname, and TO_UTF8.

Referenced by ExportBoardToSpecctraFile().

◆ ExportSESSION()

void DSN::SPECCTRA_DB::ExportSESSION ( const wxString &  aFilename)

Write the internal #SESSION instance out as a #SPECTRA DSN format file.

Parameters
aFilenameThe file to save to.

Definition at line 3711 of file specctra.cpp.

3712{
3713 if( m_session )
3714 {
3715 FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3716
3717 m_session->Format( &formatter, 0 );
3718 }
3719}
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:3597

References DSN::SESSION::Format(), m_quote_char, and m_session.

◆ fillBOUNDARY()

void DSN::SPECCTRA_DB::fillBOUNDARY ( BOARD aBoard,
BOUNDARY aBoundary 
)
private

Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tree.

Parameters
aBoardThe BOARD to get information from in order to make the BOUNDARY.
aBoundaryThe empty BOUNDARY to fill in.

Definition at line 1030 of file specctra_export.cpp.

1031{
1032 for( int cnt = 0; cnt < m_brd_outlines.OutlineCount(); cnt++ ) // Should be one outline
1033 {
1034 PATH* path = new PATH( boundary );
1035 boundary->paths.push_back( path );
1036 path->layer_id = "pcb";
1037
1038 SHAPE_LINE_CHAIN& outline = m_brd_outlines.Outline( cnt );
1039
1040 for( int ii = 0; ii < outline.PointCount(); ii++ )
1041 {
1042 wxPoint pos( outline.CPoint( ii ).x, outline.CPoint( ii ).y );
1043 path->AppendPoint( mapPt( pos ) );
1044 }
1045
1046 // Close polygon:
1047 wxPoint pos0( outline.CPoint( 0 ).x, outline.CPoint( 0 ).y );
1048 path->AppendPoint( mapPt( pos0 ) );
1049
1050 // Generate holes as keepout:
1051 for( int ii = 0; ii < m_brd_outlines.HoleCount( cnt ); ii++ )
1052 {
1053 // emit a signal layers keepout for every interior polygon left...
1054 KEEPOUT* keepout = new KEEPOUT( nullptr, T_keepout );
1055 PATH* poly_ko = new PATH( nullptr, T_polygon );
1056
1057 keepout->SetShape( poly_ko );
1058 poly_ko->SetLayerId( "signal" );
1059 m_pcb->structure->keepouts.push_back( keepout );
1060
1061 SHAPE_LINE_CHAIN& hole = m_brd_outlines.Hole( cnt, ii );
1062
1063 for( int jj = 0; jj < hole.PointCount(); jj++ )
1064 {
1065 wxPoint pos( hole.CPoint( jj ).x, hole.CPoint( jj ).y );
1066 poly_ko->AppendPoint( mapPt( pos ) );
1067 }
1068
1069 // Close polygon:
1070 wxPoint pos( hole.CPoint( 0 ).x, hole.CPoint( 0 ).y );
1071 poly_ko->AppendPoint( mapPt( pos ) );
1072 }
1073 }
1074}
Used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:906
void SetShape(ELEM *aShape)
Definition: specctra.h:930
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:583
void SetLayerId(const char *aLayerId)
Definition: specctra.h:600
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:593
STRUCTURE * structure
Definition: specctra.h:3258
KEEPOUTS keepouts
Definition: specctra.h:1670
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.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Outline(int aIndex)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
static POINT mapPt(const VECTOR2I &pt)
Convert a KiCad point into a DSN file point.

References DSN::PATH::AppendPoint(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), DSN::STRUCTURE::keepouts, m_brd_outlines, m_pcb, DSN::mapPt(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), path, DSN::BOUNDARY::paths, SHAPE_LINE_CHAIN::PointCount(), DSN::PATH::SetLayerId(), DSN::KEEPOUT::SetShape(), DSN::PCB::structure, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by FromBOARD().

◆ findLayerName()

int DSN::SPECCTRA_DB::findLayerName ( const std::string &  aLayerName) const
private

Return the PCB layer index for a given layer name, within the specctra sessionfile.

Returns
the layer index within the specctra session file, or -1 if aLayerName is not found.

Definition at line 125 of file specctra.cpp.

126{
127 for( int i = 0; i < int( m_layerIds.size() ); ++i )
128 {
129 if( 0 == aLayerName.compare( m_layerIds[i] ) )
130 return i;
131 }
132
133 return -1;
134}

References m_layerIds.

Referenced by makeTRACK(), and makeVIA().

◆ FlipFOOTPRINTs()

void DSN::SPECCTRA_DB::FlipFOOTPRINTs ( BOARD aBoard)

Flip the footprints which are on the back side of the board to the front.

Definition at line 1790 of file specctra_export.cpp.

1791{
1792 // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the top view.
1793 // Note: to export footprints, the footprints must be flipped around the X axis, otherwise
1794 // the rotation angle is not good.
1795 for( FOOTPRINT* footprint : aBoard->Footprints() )
1796 {
1797 footprint->SetFlag( 0 );
1798
1799 if( footprint->GetLayer() == B_Cu )
1800 {
1801 footprint->Flip( footprint->GetPosition(), false );
1802 footprint->SetFlag( 1 );
1803 }
1804 }
1805
1807}
FOOTPRINTS & Footprints()
Definition: board.h:307

References B_Cu, BOARD::Footprints(), and m_footprintsAreFlipped.

Referenced by ExportBoardToSpecctraFile().

◆ FromBOARD()

void DSN::SPECCTRA_DB::FromBOARD ( BOARD aBoard)

Add the entire BOARD to the PCB but does not write it out.

Note
The BOARD given to this function must have all the FOOTPRINTs on the component side of the BOARD.
See also
PCB_EDIT_FRAME::ExportToSpecctra() for an example before calling this function.
Parameters
aBoardThe BOARD to convert to a PCB.

Definition at line 1081 of file specctra_export.cpp.

1082{
1083 std::shared_ptr<NET_SETTINGS>& netSettings = aBoard->GetDesignSettings().m_NetSettings;
1084
1085 // Not all boards are exportable. Check that all reference Ids are unique, or we won't be
1086 // able to import the session file which comes back to us later from the router.
1087 {
1088 STRINGSET refs; // holds footprint reference designators
1089
1090 for( FOOTPRINT* footprint : aBoard->Footprints() )
1091 {
1092 if( footprint->GetReference() == wxEmptyString )
1093 {
1094 THROW_IO_ERROR( wxString::Format( _( "Footprint with value of '%s' has an empty "
1095 "reference designator." ),
1096 footprint->GetValue() ) );
1097 }
1098
1099 // if we cannot insert OK, that means the reference has been seen before.
1100 STRINGSET_PAIR refpair = refs.insert( TO_UTF8( footprint->GetReference() ) );
1101
1102 if( !refpair.second ) // insert failed
1103 {
1104 THROW_IO_ERROR( wxString::Format( _( "Multiple footprints have the reference "
1105 "designator '%s'." ),
1106 footprint->GetReference() ) );
1107 }
1108 }
1109 }
1110
1111 if( !m_pcb )
1113
1114 //-----<layer_descriptor>-----------------------------------------------
1115 {
1116 // Specctra wants top physical layer first, then going down to the bottom most physical
1117 // layer in physical sequence.
1118
1119 buildLayerMaps( aBoard );
1120
1121 int layerCount = aBoard->GetCopperLayerCount();
1122
1123 for( int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
1124 {
1125 LAYER* layer = new LAYER( m_pcb->structure );
1126
1127 m_pcb->structure->layers.push_back( layer );
1128
1129 layer->name = m_layerIds[pcbNdx];
1130
1131 DSN_T layerType;
1132
1133 switch( aBoard->GetLayerType( m_pcbLayer2kicad[pcbNdx] ) )
1134 {
1135 default:
1136 case LT_SIGNAL: layerType = T_signal; break;
1137 case LT_POWER: layerType = T_power; break;
1138
1139 // Freerouter does not support type "mixed", only signal and power.
1140 // Remap "mixed" to "signal".
1141 case LT_MIXED: layerType = T_signal; break;
1142 case LT_JUMPER: layerType = T_jumper; break;
1143 }
1144
1145 layer->layer_type = layerType;
1146
1147 layer->properties.push_back( PROPERTY() );
1148 PROPERTY* property = &layer->properties.back();
1149 property->name = "index";
1150 char temp[32];
1151 sprintf( temp, "%d", pcbNdx );
1152 property->value = temp;
1153 }
1154 }
1155
1156 // a space in a quoted token is NOT a terminator, true establishes this.
1158
1159 //-----<unit_descriptor> & <resolution_descriptor>--------------------
1160 {
1161 // Tell freerouter to use "tenths of micrometers", which is 100 nm resolution. Possibly
1162 // more resolution is possible in freerouter, but it would need testing.
1163
1164 m_pcb->unit->units = T_um;
1165 m_pcb->resolution->units = T_um;
1166 m_pcb->resolution->value = 10; // tenths of a um
1167 }
1168
1169 //-----<boundary_descriptor>------------------------------------------
1170 {
1171 // Because fillBOUNDARY() can throw an exception, we link in an empty boundary so the
1172 // BOUNDARY does not get lost in the event of of an exception.
1173 BOUNDARY* boundary = new BOUNDARY( 0 );
1174
1175 m_pcb->structure->SetBOUNDARY( boundary );
1176 fillBOUNDARY( aBoard, boundary );
1177 }
1178
1179 //-----<rules>--------------------------------------------------------
1180 {
1181 char rule[80];
1182 int defaultTrackWidth = netSettings->m_DefaultNetClass->GetTrackWidth();
1183 int defaultClearance = netSettings->m_DefaultNetClass->GetClearance();
1184 double clearance = scale( defaultClearance );
1185
1186 STRINGS& rules = m_pcb->structure->rules->rules;
1187
1188 sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
1189 rules.push_back( rule );
1190
1191 sprintf( rule, "(clearance %.6g)", clearance + safetyMargin );
1192 rules.push_back( rule );
1193
1194 // On a high density board (4 mil tracks, 4 mil spacing) a typical solder mask clearance
1195 // will be 2-3 mils. This exposes 2 to 3 mils of bare board around each pad, and would
1196 // leave only 1 to 2 mils of solder mask between the solder mask's boundary and the edge of
1197 // any trace within "clearance" of the pad. So we need at least 2 mils *extra* clearance
1198 // for traces which would come near a pad on a different net. So if the baseline trace to
1199 // trace clearance was 4 mils, then the SMD to trace clearance should be at least 6 mils.
1200 double default_smd = clearance + safetyMargin;
1201
1202 if( default_smd <= 6.0 )
1203 default_smd = 6.0;
1204
1205 sprintf( rule, "(clearance %.6g (type default_smd))", default_smd );
1206
1207 rules.push_back( rule );
1208
1209 // Pad to pad spacing on a single SMT part can be closer than our clearance. We don't want
1210 // freerouter complaining about that, so output a significantly smaller pad to pad
1211 // clearance to freerouter.
1212 clearance = scale( defaultClearance ) / 4;
1213
1214 sprintf( rule, "(clearance %.6g (type smd_smd))", clearance );
1215 rules.push_back( rule );
1216 }
1217
1218 //-----<zones (not keepout areas) become planes>--------------------------------
1219 // Note: only zones are output here, keepout areas are created later.
1220 {
1221 int netlessZones = 0;
1222
1223 for( ZONE* zone : aBoard->Zones() )
1224 {
1225 if( zone->GetIsRuleArea() )
1226 continue;
1227
1228 // Currently, we export only copper layers
1229 if( ! IsCopperLayer( zone->GetLayer() ) )
1230 continue;
1231
1232 COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure );
1233
1234 m_pcb->structure->planes.push_back( plane );
1235
1236 PATH* mainPolygon = new PATH( plane, T_polygon );
1237
1238 plane->SetShape( mainPolygon );
1239 plane->name = TO_UTF8( zone->GetNetname() );
1240
1241 if( plane->name.size() == 0 )
1242 {
1243 char name[32];
1244
1245 // This is one of those no connection zones, netcode=0, and it has no name.
1246 // Create a unique, bogus netname.
1247 NET* no_net = new NET( m_pcb->network );
1248
1249 sprintf( name, "@:no_net_%d", netlessZones++ );
1250 no_net->net_id = name;
1251
1252 // add the bogus net name to network->nets.
1253 m_pcb->network->nets.push_back( no_net );
1254
1255 // use the bogus net name in the netless zone.
1256 plane->name = no_net->net_id;
1257 }
1258
1259 mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ];
1260
1261 // Handle the main outlines
1262 SHAPE_POLY_SET::ITERATOR iterator;
1263 wxPoint startpoint;
1264 bool is_first_point = true;
1265
1266 for( iterator = zone->IterateWithHoles(); iterator; iterator++ )
1267 {
1268 wxPoint point( iterator->x, iterator->y );
1269
1270 if( is_first_point )
1271 {
1272 startpoint = point;
1273 is_first_point = false;
1274 }
1275
1276 mainPolygon->AppendPoint( mapPt( point ) );
1277
1278 // this was the end of the main polygon
1279 if( iterator.IsEndContour() )
1280 {
1281 // Close polygon
1282 mainPolygon->AppendPoint( mapPt( startpoint ) );
1283 break;
1284 }
1285 }
1286
1287 WINDOW* window = 0;
1288 PATH* cutout = 0;
1289
1290 bool isStartContour = true;
1291
1292 // handle the cutouts
1293 for( iterator++; iterator; iterator++ )
1294 {
1295 if( isStartContour )
1296 {
1297 is_first_point = true;
1298 window = new WINDOW( plane );
1299 plane->AddWindow( window );
1300
1301 cutout = new PATH( window, T_polygon );
1302 window->SetShape( cutout );
1303 cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ];
1304 }
1305
1306 // If the point in this iteration is the last of the contour, the next iteration
1307 // will start with a new contour.
1308 isStartContour = iterator.IsEndContour();
1309
1310 wxASSERT( window );
1311 wxASSERT( cutout );
1312
1313 wxPoint point(iterator->x, iterator->y );
1314
1315 if( is_first_point )
1316 {
1317 startpoint = point;
1318 is_first_point = false;
1319 }
1320
1321 cutout->AppendPoint( mapPt( point ) );
1322
1323 // Close the polygon
1324 if( iterator.IsEndContour() )
1325 cutout->AppendPoint( mapPt( startpoint ) );
1326 }
1327 }
1328 }
1329
1330 //-----<zones flagged keepout areas become keepout>--------------------------------
1331 {
1332 for( ZONE* zone : aBoard->Zones() )
1333 {
1334 if( !zone->GetIsRuleArea() )
1335 continue;
1336
1337 // Keepout areas have a type: T_place_keepout, T_via_keepout, T_wire_keepout,
1338 // T_bend_keepout, T_elongate_keepout, T_keepout.
1339 // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
1340 DSN_T keepout_type;
1341
1342 if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
1343 keepout_type = T_keepout;
1344 else if( zone->GetDoNotAllowVias() )
1345 keepout_type = T_via_keepout;
1346 else if( zone->GetDoNotAllowTracks() )
1347 keepout_type = T_wire_keepout;
1348 else
1349 keepout_type = T_keepout;
1350
1351 // Now, build keepout polygon on each copper layer where the zone
1352 // keepout is living (keepout zones can live on many copper layers)
1353 const int copperCount = aBoard->GetCopperLayerCount();
1354
1355 for( int layer = 0; layer < copperCount; layer++ )
1356 {
1357 if( layer == copperCount - 1 )
1358 layer = B_Cu;
1359
1360 if( !zone->IsOnLayer( PCB_LAYER_ID( layer ) ) )
1361 continue;
1362
1363 KEEPOUT* keepout = new KEEPOUT( m_pcb->structure, keepout_type );
1364 m_pcb->structure->keepouts.push_back( keepout );
1365
1366 PATH* mainPolygon = new PATH( keepout, T_polygon );
1367 keepout->SetShape( mainPolygon );
1368
1369 mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
1370
1371 // Handle the main outlines
1372 SHAPE_POLY_SET::ITERATOR iterator;
1373 bool is_first_point = true;
1374 wxPoint startpoint;
1375
1376 for( iterator = zone->IterateWithHoles(); iterator; iterator++ )
1377 {
1378 wxPoint point( iterator->x, iterator->y );
1379
1380 if( is_first_point )
1381 {
1382 startpoint = point;
1383 is_first_point = false;
1384 }
1385
1386 mainPolygon->AppendPoint( mapPt( point ) );
1387
1388 // this was the end of the main polygon
1389 if( iterator.IsEndContour() )
1390 {
1391 mainPolygon->AppendPoint( mapPt( startpoint ) );
1392 break;
1393 }
1394 }
1395
1396 WINDOW* window = nullptr;
1397 PATH* cutout = nullptr;
1398
1399 bool isStartContour = true;
1400
1401 // handle the cutouts
1402 for( iterator++; iterator; iterator++ )
1403 {
1404 if( isStartContour )
1405 {
1406 is_first_point = true;
1407 window = new WINDOW( keepout );
1408 keepout->AddWindow( window );
1409
1410 cutout = new PATH( window, T_polygon );
1411 window->SetShape( cutout );
1412 cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ];
1413 }
1414
1415 isStartContour = iterator.IsEndContour();
1416
1417 wxASSERT( window );
1418 wxASSERT( cutout );
1419
1420 wxPoint point(iterator->x, iterator->y );
1421
1422 if( is_first_point )
1423 {
1424 startpoint = point;
1425 is_first_point = false;
1426 }
1427
1428 cutout->AppendPoint( mapPt(point) );
1429
1430 // Close the polygon
1431 if( iterator.IsEndContour() )
1432 cutout->AppendPoint( mapPt( startpoint ) );
1433 }
1434 }
1435 }
1436 }
1437
1438 //-----<build the images, components, and netlist>-----------------------
1439 {
1441 std::string componentId;
1442 int highestNetCode = 0;
1443 NETINFO_LIST& netInfo = aBoard->GetNetInfo();
1444
1445 // find the highest numbered netCode within the board.
1446 for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1447 highestNetCode = std::max( highestNetCode, i->GetNetCode() );
1448
1449 deleteNETs();
1450
1451 // expand the net vector to highestNetCode+1, setting empty to NULL
1452 m_nets.resize( highestNetCode + 1, nullptr );
1453
1454 for( unsigned i = 1 /* skip "No Net" at [0] */; i < m_nets.size(); ++i )
1455 m_nets[i] = new NET( m_pcb->network );
1456
1457 for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1458 {
1459 if( i->GetNetCode() > 0 )
1460 m_nets[i->GetNetCode()]->net_id = TO_UTF8( i->GetNetname() );
1461 }
1462
1463 m_padstackset.clear();
1464
1465 for( FOOTPRINT* footprint : aBoard->Footprints() )
1466 {
1467 IMAGE* image = makeIMAGE( aBoard, footprint );
1468
1469 componentId = TO_UTF8( footprint->GetReference() );
1470
1471 // Create a net list entry for all the actual pins in the current footprint.
1472 // Location of this code is critical because we fabricated some pin names to ensure
1473 // unique-ness within a footprint, and the life of this 'IMAGE* image' is not
1474 // necessarily long. The exported netlist will have some fabricated pin names in it.
1475 // If you don't like fabricated pin names, then make sure all pads within your
1476 // FOOTPRINTs are uniquely named!
1477 for( unsigned p = 0; p < image->pins.size(); ++p )
1478 {
1479 PIN* pin = &image->pins[p];
1480 int netcode = pin->kiNetCode;
1481
1482 if( netcode > 0 )
1483 {
1484 NET* net = m_nets[netcode];
1485
1486 net->pins.push_back( empty );
1487
1488 PIN_REF& pin_ref = net->pins.back();
1489
1490 pin_ref.component_id = componentId;
1491 pin_ref.pin_id = pin->pin_id;
1492 }
1493 }
1494
1496
1497 if( registered != image )
1498 {
1499 // If our new 'image' is not a unique IMAGE, delete it.
1500 // and use the registered one, known as 'image' after this.
1501 delete image;
1502 image = registered;
1503 }
1504
1505 COMPONENT* comp = m_pcb->placement->LookupCOMPONENT( image->GetImageId() );
1506 PLACE* place = new PLACE( comp );
1507
1508 comp->places.push_back( place );
1509
1510 place->SetRotation( footprint->GetOrientationDegrees() );
1511 place->SetVertex( mapPt( footprint->GetPosition() ) );
1512 place->component_id = componentId;
1513 place->part_number = TO_UTF8( footprint->GetValue() );
1514
1515 // footprint is flipped from bottom side, set side to T_back
1516 if( footprint->GetFlag() )
1517 {
1518 EDA_ANGLE angle = ANGLE_180 - footprint->GetOrientation();
1519 place->SetRotation( angle.Normalize().AsDegrees() );
1520
1521 place->side = T_back;
1522 }
1523 }
1524
1525 // copy the SPECCTRA_DB::padstackset to the LIBRARY. Since we are
1526 // removing, do not increment the iterator
1527 for( PADSTACKSET::iterator i = m_padstackset.begin(); i != m_padstackset.end();
1528 i = m_padstackset.begin() )
1529 {
1530 PADSTACKSET::auto_type ps = m_padstackset.release( i );
1531 PADSTACK* padstack = ps.release();
1532
1533 m_pcb->library->AddPadstack( padstack );
1534 }
1535
1536 // copy our SPECCTRA_DB::nets to the pcb->network
1537 for( unsigned n = 1; n < m_nets.size(); ++n )
1538 {
1539 NET* net = m_nets[n];
1540
1541 if( net->pins.size() )
1542 {
1543 // give ownership to pcb->network
1544 m_pcb->network->nets.push_back( net );
1545 m_nets[n] = 0;
1546 }
1547 }
1548 }
1549
1550 //-----< output vias used in netclasses >-----------------------------------
1551 {
1552 // Assume the netclass vias are all the same kind of thru, blind, or buried vias.
1553 // This is in lieu of either having each netclass via have its own layer pair in
1554 // the netclass dialog, or such control in the specctra export dialog.
1555
1556 m_top_via_layer = 0; // first specctra cu layer is number zero.
1558
1559 // Add the via from the Default netclass first. The via container
1560 // in pcb->library preserves the sequence of addition.
1561
1562 PADSTACK* via = makeVia( netSettings->m_DefaultNetClass->GetViaDiameter(),
1563 netSettings->m_DefaultNetClass->GetViaDrill(),
1565
1566 // we AppendVia() this first one, there is no way it can be a duplicate,
1567 // the pcb->library via container is empty at this point. After this,
1568 // we'll have to use LookupVia().
1569 wxASSERT( m_pcb->library->vias.size() == 0 );
1570 m_pcb->library->AppendVia( via );
1571
1572 // set the "spare via" index at the start of the
1573 // pcb->library->spareViaIndex = pcb->library->vias.size();
1574
1575 // output the non-Default netclass vias
1576 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
1577 {
1578 via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1580
1581 // maybe add 'via' to the library, but only if unique.
1583
1584 if( registered != via )
1585 delete via;
1586 }
1587 }
1588
1589 //-----<create the wires from tracks>-----------------------------------
1590 {
1591 // export all of them for now, later we'll decide what controls we need on this.
1592 std::string netname;
1593 WIRING* wiring = m_pcb->wiring;
1594 PATH* path = 0;
1595
1596 int old_netcode = -1;
1597 int old_width = -1;
1598 int old_layer = UNDEFINED_LAYER;
1599
1600 for( PCB_TRACK* track : aBoard->Tracks() )
1601 {
1602 if( !track->IsType( { PCB_TRACE_T, PCB_ARC_T } ) )
1603 continue;
1604
1605 int netcode = track->GetNetCode();
1606
1607 if( netcode == 0 )
1608 continue;
1609
1610 if( old_netcode != netcode
1611 || old_width != track->GetWidth()
1612 || old_layer != track->GetLayer()
1613 || ( path && path->points.back() != mapPt( track->GetStart() ) ) )
1614 {
1615 old_width = track->GetWidth();
1616 old_layer = track->GetLayer();
1617
1618 if( old_netcode != netcode )
1619 {
1620 old_netcode = netcode;
1621 NETINFO_ITEM* net = aBoard->FindNet( netcode );
1622 wxASSERT( net );
1623 netname = TO_UTF8( net->GetNetname() );
1624 }
1625
1626 WIRE* wire = new WIRE( wiring );
1627
1628 wiring->wires.push_back( wire );
1629 wire->net_id = netname;
1630
1631 if( track->IsLocked() )
1632 wire->wire_type = T_fix; // tracks with fix property are not returned in .ses files
1633 else
1634 wire->wire_type = T_route; // could be T_protect
1635
1636 int kiLayer = track->GetLayer();
1637 int pcbLayer = m_kicadLayer2pcb[kiLayer];
1638
1639 path = new PATH( wire );
1640 wire->SetShape( path );
1641 path->layer_id = m_layerIds[pcbLayer];
1642 path->aperture_width = scale( old_width );
1643 path->AppendPoint( mapPt( track->GetStart() ) );
1644 }
1645
1646 if( path ) // Should not occur
1647 path->AppendPoint( mapPt( track->GetEnd() ) );
1648 }
1649 }
1650
1651 //-----<export the existing real BOARD instantiated vias>-----------------
1652 {
1653 // Export all vias, once per unique size and drill diameter combo.
1654 for( PCB_TRACK* track : aBoard->Tracks() )
1655 {
1656 if( track->Type() != PCB_VIA_T )
1657 continue;
1658
1659 PCB_VIA* via = static_cast<PCB_VIA*>( track );
1660 int netcode = via->GetNetCode();
1661
1662 if( netcode == 0 )
1663 continue;
1664
1665 PADSTACK* padstack = makeVia( via );
1666 PADSTACK* registered = m_pcb->library->LookupVia( padstack );
1667
1668 // if the one looked up is not our padstack, then delete our padstack
1669 // since it was a duplicate of one already registered.
1670 if( padstack != registered )
1671 delete padstack;
1672
1673 WIRE_VIA* dsnVia = new WIRE_VIA( m_pcb->wiring );
1674
1675 m_pcb->wiring->wire_vias.push_back( dsnVia );
1676
1677 dsnVia->padstack_id = registered->padstack_id;
1678 dsnVia->vertexes.push_back( mapPt( via->GetPosition() ) );
1679
1680 NETINFO_ITEM* net = aBoard->FindNet( netcode );
1681 wxASSERT( net );
1682
1683 dsnVia->net_id = TO_UTF8( net->GetNetname() );
1684
1685 if( via->IsLocked() )
1686 dsnVia->via_type = T_fix; // vias with fix property are not returned in .ses files
1687 else
1688 dsnVia->via_type = T_route; // could be T_protect
1689 }
1690 }
1691
1692 //-----<via_descriptor>-------------------------------------------------
1693 {
1694 // The pcb->library will output <padstack_descriptors> which is a combined list of part
1695 // padstacks and via padstacks. specctra dsn uses the <via_descriptors> to say which of
1696 // those padstacks are vias.
1697
1698 // Output the vias in the padstack list here, by name only. This must be done after
1699 // exporting existing vias as WIRE_VIAs.
1700 VIA* vias = m_pcb->structure->via;
1701
1702 for( unsigned viaNdx = 0; viaNdx < m_pcb->library->vias.size(); ++viaNdx )
1703 vias->AppendVia( m_pcb->library->vias[viaNdx].padstack_id.c_str() );
1704 }
1705
1706 //-----<output NETCLASSs>----------------------------------------------------
1707
1708 exportNETCLASS( netSettings->m_DefaultNetClass, aBoard );
1709
1710 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
1711 exportNETCLASS( netclass, aBoard );
1712}
const char * name
Definition: DXF_plotter.cpp:56
@ LT_POWER
Definition: board.h:146
@ LT_MIXED
Definition: board.h:147
@ LT_JUMPER
Definition: board.h:148
@ LT_SIGNAL
Definition: board.h:145
std::shared_ptr< NET_SETTINGS > m_NetSettings
ZONES & Zones()
Definition: board.h:313
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1382
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:418
TRACKS & Tracks()
Definition: board.h:304
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:602
Implement a <component_descriptor> in the specctra dsn spec.
Definition: specctra.h:1768
PLACES places
Definition: specctra.h:1809
A <plane_descriptor> in the specctra dsn spec.
Definition: specctra.h:1353
void AddWindow(WINDOW *aWindow)
Definition: specctra.h:947
std::string name
Definition: specctra.h:1012
PROPERTIES properties
Definition: specctra.h:1288
DSN_T layer_type
one of: T_signal, T_power, T_mixed, T_jumper
Definition: specctra.h:1279
std::string name
Definition: specctra.h:1278
PADSTACK * LookupVia(PADSTACK *aVia)
Add the via only if one exactly like it does not already exist in the padstack container.
Definition: specctra.h:2387
void AppendVia(PADSTACK *aVia)
Add aVia to the internal via container.
Definition: specctra.h:2365
PADSTACKS vias
Definition: specctra.h:2448
IMAGE * LookupIMAGE(IMAGE *aImage)
Add the image only if one exactly like it does not already exist in the image container.
Definition: specctra.h:2333
void AddPadstack(PADSTACK *aPadstack)
Definition: specctra.h:2272
A <net_descriptor> in the DSN spec.
Definition: specctra.h:2597
PIN_REFS pins
Definition: specctra.h:2700
std::string net_id
Definition: specctra.h:2695
bool space_in_quoted_tokens
Definition: specctra.h:381
std::string layer_id
Definition: specctra.h:650
UNIT_RES * unit
Definition: specctra.h:3257
WIRING * wiring
Definition: specctra.h:3262
PLACEMENT * placement
Definition: specctra.h:3259
PARSER * parser
Definition: specctra.h:3255
UNIT_RES * resolution
Definition: specctra.h:3256
LIBRARY * library
Definition: specctra.h:3260
COMPONENT * LookupCOMPONENT(const std::string &imageName)
Look up a COMPONENT by name.
Definition: specctra.h:1838
Implement a <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1688
void SetVertex(const POINT &aVertex)
Definition: specctra.h:1716
std::string part_number
Definition: specctra.h:1758
std::string component_id
reference designator
Definition: specctra.h:1733
void SetRotation(double aRotation)
Definition: specctra.h:1723
DSN_T side
Definition: specctra.h:1735
IMAGE * makeIMAGE(BOARD *aBoard, FOOTPRINT *aFootprint)
Allocates an I::MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT.
void buildLayerMaps(BOARD *aBoard)
Create a few data translation structures for layer name and number mapping between the DSN::PCB struc...
Definition: specctra.cpp:76
void fillBOUNDARY(BOARD *aBoard, BOUNDARY *aBoundary)
Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tre...
static PCB * MakePCB()
Make a PCB with all the default ELEMs and parts on the heap.
Definition: specctra.cpp:3722
PADSTACKSET m_padstackset
Definition: specctra.h:4002
void exportNETCLASS(const std::shared_ptr< NETCLASS > &aNetClass, BOARD *aBoard)
Export aNetClass to the DSN file.
COPPER_PLANES planes
Definition: specctra.h:1672
RULE * rules
Definition: specctra.h:1668
void SetBOUNDARY(BOUNDARY *aBoundary)
Definition: specctra.h:1582
LAYERS layers
Definition: specctra.h:1660
DSN_T units
Definition: specctra.h:433
A <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1039
void AppendVia(const char *aViaName)
Definition: specctra.h:1047
void SetShape(ELEM *aShape)
Definition: specctra.h:858
A <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2990
DSN_T via_type
Definition: specctra.h:3123
POINTS vertexes
Definition: specctra.h:3120
std::string net_id
Definition: specctra.h:3121
std::string padstack_id
Definition: specctra.h:3119
A <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2881
void SetShape(ELEM *aShape)
Definition: specctra.h:2901
DSN_T wire_type
Definition: specctra.h:2975
std::string net_id
Definition: specctra.h:2973
A <wiring_descriptor> in the specctra dsn spec.
Definition: specctra.h:3137
WIRES wires
Definition: specctra.h:3174
WIRE_VIAS wire_vias
Definition: specctra.h:3175
const wxString & GetNetname() const
Definition: netinfo.h:119
Container for NETINFO_ITEM elements, which are the nets.
Definition: netinfo.h:324
iterator begin() const
Definition: netinfo.h:444
iterator end() const
Definition: netinfo.h:449
Base class for iterating over all vertices in a given SHAPE_POLY_SET.
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
static bool registered
Definition: coroutines.cpp:128
#define _(s)
static constexpr EDA_ANGLE & ANGLE_180
Definition: eda_angle.h:416
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:823
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
std::vector< std::string > STRINGS
Definition: specctra.h:166
std::set< std::string > STRINGSET
std::pair< STRINGSET::iterator, bool > STRINGSET_PAIR
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
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
DSN::T DSN_T
Definition: specctra.h:48
A <pin_reference> definition in the specctra dsn spec.
Definition: specctra.h:2456
std::string pin_id
Definition: specctra.h:2482
std::string component_id
Definition: specctra.h:2481
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102

References _, DSN::LIBRARY::AddPadstack(), DSN::KEEPOUT::AddWindow(), PNS::angle(), ANGLE_180, DSN::PATH::AppendPoint(), DSN::VIA::AppendVia(), DSN::LIBRARY::AppendVia(), B_Cu, NETINFO_LIST::begin(), buildLayerMaps(), DSN::PLACE::component_id, DSN::PIN_REF::component_id, deleteNETs(), empty(), NETINFO_LIST::end(), exportNETCLASS(), fillBOUNDARY(), BOARD::FindNet(), BOARD::Footprints(), Format(), BOARD::GetCopperLayerCount(), BOARD::GetDesignSettings(), BOARD::GetLayerType(), BOARD::GetNetInfo(), NETINFO_ITEM::GetNetname(), image, IsCopperLayer(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), DSN::STRUCTURE::keepouts, DSN::PATH::layer_id, DSN::LAYER::layer_type, DSN::STRUCTURE::layers, DSN::PCB::library, DSN::PLACEMENT::LookupCOMPONENT(), DSN::LIBRARY::LookupIMAGE(), DSN::LIBRARY::LookupVia(), LT_JUMPER, LT_MIXED, LT_POWER, LT_SIGNAL, m_bot_via_layer, m_kicadLayer2pcb, m_layerIds, m_nets, BOARD_DESIGN_SETTINGS::m_NetSettings, m_padstackset, m_pcb, m_pcbLayer2kicad, m_top_via_layer, makeIMAGE(), MakePCB(), makeVia(), DSN::mapPt(), name, DSN::KEEPOUT::name, DSN::LAYER::name, DSN::NET::net_id, DSN::WIRE::net_id, DSN::WIRE_VIA::net_id, DSN::NETWORK::nets, DSN::PCB::network, DSN::WIRE_VIA::padstack_id, DSN::PCB::parser, DSN::PLACE::part_number, path, PCB_VIA_T, pin, DSN::PIN_REF::pin_id, DSN::NET::pins, DSN::PCB::placement, DSN::COMPONENT::places, DSN::STRUCTURE::planes, DSN::LAYER::properties, registered, DSN::PCB::resolution, DSN::RULE::rules, DSN::STRUCTURE::rules, safetyMargin, DSN::scale(), DSN::STRUCTURE::SetBOUNDARY(), DSN::PLACE::SetRotation(), DSN::WINDOW::SetShape(), DSN::KEEPOUT::SetShape(), DSN::WIRE::SetShape(), DSN::PLACE::SetVertex(), DSN::PLACE::side, DSN::PARSER::space_in_quoted_tokens, DSN::PCB::structure, THROW_IO_ERROR, TO_UTF8, BOARD::Tracks(), UNDEFINED_LAYER, DSN::PCB::unit, DSN::UNIT_RES::units, DSN::UNIT_RES::value, DSN::WIRE_VIA::vertexes, via, DSN::STRUCTURE::via, DSN::WIRE_VIA::via_type, DSN::LIBRARY::vias, DSN::WIRE::wire_type, DSN::WIRING::wire_vias, DSN::WIRING::wires, DSN::PCB::wiring, and BOARD::Zones().

Referenced by ExportBoardToSpecctraFile().

◆ FromSESSION()

void DSN::SPECCTRA_DB::FromSESSION ( BOARD aBoard)

Add the entire #SESSION info to a BOARD but does not write it out.

The BOARD given to this function will have all its tracks and via's replaced, and all its components are subject to being moved.

Parameters
aBoardThe BOARD to merge the #SESSION information into.

Definition at line 337 of file specctra_import.cpp.

338{
339 m_sessionBoard = aBoard; // not owned here
340
341 if( !m_session )
342 THROW_IO_ERROR( _("Session file is missing the \"session\" section") );
343
344 if( !m_session->route )
345 THROW_IO_ERROR( _("Session file is missing the \"routes\" section") );
346
347 if( !m_session->route->library )
348 THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") );
349
350 // delete the old tracks and vias but save locked tracks/vias; they will be re-added later
351 std::vector<PCB_TRACK*> locked;
352
353 while( !aBoard->Tracks().empty() )
354 {
355 PCB_TRACK* track = aBoard->Tracks().back();
356 aBoard->Tracks().pop_back();
357
358 if( track->IsLocked() )
359 locked.push_back( track );
360 else
361 delete track;
362 }
363
364 aBoard->DeleteMARKERs();
365
366 buildLayerMaps( aBoard );
367
368 // Add locked tracks: because they are exported as Fix tracks, they are not
369 // in .ses file.
370 for( PCB_TRACK* track: locked )
371 aBoard->Add( track );
372
373 if( m_session->placement )
374 {
375 // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
376 // each COMPONENT, reposition and re-orient each component and put on
377 // correct side of the board.
379
380 for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
381 {
382 PLACES& places = comp->places;
383 for( unsigned i=0; i<places.size(); ++i )
384 {
385 PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
386
387 wxString reference = FROM_UTF8( place->component_id.c_str() );
388 FOOTPRINT* footprint = aBoard->FindFootprintByReference( reference );
389
390 if( !footprint )
391 {
392 THROW_IO_ERROR( wxString::Format( _( "Reference '%s' not found." ),
393 reference ) );
394 }
395
396 if( !place->hasVertex )
397 continue;
398
399 UNIT_RES* resolution = place->GetUnits();
400 wxASSERT( resolution );
401
402 wxPoint newPos = mapPt( place->vertex, resolution );
403 footprint->SetPosition( newPos );
404
405 if( place->side == T_front )
406 {
407 // convert from degrees to tenths of degrees used in KiCad.
408 EDA_ANGLE orientation( place->rotation, DEGREES_T );
409
410 if( footprint->GetLayer() != F_Cu )
411 {
412 // footprint is on copper layer (back)
413 footprint->Flip( footprint->GetPosition(), false );
414 }
415
416 footprint->SetOrientation( orientation );
417 }
418 else if( place->side == T_back )
419 {
420 EDA_ANGLE orientation( place->rotation + 180.0, DEGREES_T );
421
422 if( footprint->GetLayer() != B_Cu )
423 {
424 // footprint is on component layer (front)
425 footprint->Flip( footprint->GetPosition(), false );
426 }
427
428 footprint->SetOrientation( orientation );
429 }
430 else
431 {
432 // as I write this, the PARSER *is* catching this, so we should never see below:
433 wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") );
434 }
435 }
436 }
437 }
438
440
441 // Walk the NET_OUTs and create tracks and vias anew.
442 NET_OUTS& net_outs = m_session->route->net_outs;
443 for( NET_OUTS::iterator net = net_outs.begin(); net!=net_outs.end(); ++net )
444 {
445 int netoutCode = 0;
446
447 // page 143 of spec says wire's net_id is optional
448 if( net->net_id.size() )
449 {
450 wxString netName = FROM_UTF8( net->net_id.c_str() );
451 NETINFO_ITEM* netinfo = aBoard->FindNet( netName );
452
453 if( netinfo )
454 netoutCode = netinfo->GetNetCode();
455 }
456
457 WIRES& wires = net->wires;
458 for( unsigned i = 0; i<wires.size(); ++i )
459 {
460 WIRE* wire = &wires[i];
461 DSN_T shape = wire->shape->Type();
462
463 if( shape != T_path )
464 {
465 /*
466 * shape == T_polygon is expected from freerouter if you have a zone on a non-
467 * "power" type layer, i.e. a T_signal layer and the design does a round-trip
468 * back in as session here. We kept our own zones in the BOARD, so ignore this
469 * so called 'wire'.
470
471 wxString netId = FROM_UTF8( wire->net_id.c_str() );
472 THROW_IO_ERROR( wxString::Format( _( "Unsupported wire shape: '%s' for net: '%s'" ),
473 DLEX::GetTokenString(shape).GetData(),
474 netId.GetData() ) );
475 */
476 }
477 else
478 {
479 PATH* path = (PATH*) wire->shape;
480
481 for( unsigned pt=0; pt < path->points.size()-1; ++pt )
482 {
483 PCB_TRACK* track = makeTRACK( wire, path, pt, netoutCode );
484 aBoard->Add( track );
485 }
486 }
487 }
488
489 WIRE_VIAS& wire_vias = net->wire_vias;
491
492 for( unsigned i=0; i<wire_vias.size(); ++i )
493 {
494 int netCode = 0;
495
496 // page 144 of spec says wire_via's net_id is optional
497 if( net->net_id.size() )
498 {
499 wxString netName = FROM_UTF8( net->net_id.c_str() );
500 NETINFO_ITEM* netvia = aBoard->FindNet( netName );
501
502 if( netvia )
503 netCode = netvia->GetNetCode();
504 }
505
506 WIRE_VIA* wire_via = &wire_vias[i];
507
508 // example: (via Via_15:8_mil 149000 -71000 )
509
510 PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() );
511 if( !padstack )
512 {
513 // Dick Feb 29, 2008:
514 // Freerouter has a bug where it will not round trip all vias. Vias which have
515 // a (use_via) element will be round tripped. Vias which do not, don't come back
516 // in in the session library, even though they may be actually used in the
517 // pre-routed, protected wire_vias. So until that is fixed, create the padstack
518 // from its name as a work around.
519 wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
520
521 THROW_IO_ERROR( wxString::Format( _( "A wire_via refers to missing padstack '%s'." ),
522 psid ) );
523 }
524
525 std::shared_ptr<NET_SETTINGS>& netSettings = aBoard->GetDesignSettings().m_NetSettings;
526
527 int via_drill_default = netSettings->m_DefaultNetClass->GetViaDrill();
528
529 for( unsigned v = 0; v < wire_via->vertexes.size(); ++v )
530 {
531 PCB_VIA* via = makeVIA( wire_via, padstack, wire_via->vertexes[v], netCode,
532 via_drill_default );
533 aBoard->Add( via );
534 }
535 }
536 }
537}
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:167
virtual bool IsLocked() const
Definition: board_item.cpp:65
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:670
FOOTPRINT * FindFootprintByReference(const wxString &aReference) const
Search for a FOOTPRINT within this board with the given reference designator.
Definition: board.cpp:1403
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:876
virtual UNIT_RES * GetUnits() const
Return the units for this section.
Definition: specctra.cpp:3765
DSN_T Type() const
Definition: specctra.h:210
A <library_descriptor> in the specctra dsn specification.
Definition: specctra.h:2258
COMPONENTS components
Definition: specctra.h:1882
POINT vertex
Definition: specctra.h:1740
bool hasVertex
Definition: specctra.h:1739
double rotation
Definition: specctra.h:1737
UNIT_RES * GetUnits() const override
Return the units for this section.
Definition: specctra.h:3475
NET_OUTS net_outs
Definition: specctra.h:3518
LIBRARY * library
Definition: specctra.h:3517
PLACEMENT * placement
Definition: specctra.h:3630
ROUTE * route
Definition: specctra.h:3632
PCB_TRACK * makeTRACK(WIRE *wire, PATH *aPath, int aPointIndex, int aNetcode)
Create a #TRACK form the #PATH and BOARD info.
PCB_VIA * makeVIA(WIRE_VIA *aVia, PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
Instantiate a KiCad #VIA on the heap and initializes it with internal values consistent with the give...
A holder for either a T_unit or T_resolution object which are usually mutually exclusive in the dsn g...
Definition: specctra.h:403
const std::string & GetPadstackId()
Definition: specctra.h:3001
ELEM * shape
Definition: specctra.h:2971
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:1636
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:1766
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
int GetNetCode() const
Definition: netinfo.h:113
@ DEGREES_T
Definition: eda_angle.h:31
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
boost::ptr_vector< NET_OUT > NET_OUTS
Definition: specctra.h:3451
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2983
boost::ptr_vector< PLACE > PLACES
Definition: specctra.h:1761
boost::ptr_vector< WIRE_VIA > WIRE_VIAS
Definition: specctra.h:3130
boost::ptr_vector< COMPONENT > COMPONENTS
Definition: pcb_netlist.h:205

References _, BOARD::Add(), B_Cu, buildLayerMaps(), DSN::PLACE::component_id, DSN::PLACEMENT::components, DEGREES_T, BOARD::DeleteMARKERs(), F_Cu, BOARD::FindFootprintByReference(), BOARD::FindNet(), FOOTPRINT::Flip(), Format(), FROM_UTF8(), BOARD::GetDesignSettings(), BOARD_ITEM::GetLayer(), NETINFO_ITEM::GetNetCode(), DSN::WIRE_VIA::GetPadstackId(), FOOTPRINT::GetPosition(), DSN::ELEM::GetUnits(), DSN::ROUTE::GetUnits(), DSN::PLACE::hasVertex, BOARD_ITEM::IsLocked(), library, DSN::ROUTE::library, locked, BOARD_DESIGN_SETTINGS::m_NetSettings, m_routeResolution, m_session, m_sessionBoard, makeTRACK(), makeVIA(), DSN::mapPt(), DSN::ROUTE::net_outs, path, DSN::SESSION::placement, DSN::PLACE::rotation, DSN::SESSION::route, FOOTPRINT::SetOrientation(), FOOTPRINT::SetPosition(), DSN::WIRE::shape, DSN::PLACE::side, THROW_IO_ERROR, BOARD::Tracks(), DSN::ELEM::Type(), DSN::PLACE::vertex, DSN::WIRE_VIA::vertexes, and via.

Referenced by PCB_EDIT_FRAME::ImportSpecctraSession().

◆ GetPCB()

PCB * DSN::SPECCTRA_DB::GetPCB ( )
inline

Definition at line 3694 of file specctra.h.

3694{ return m_pcb; }

References m_pcb.

Referenced by main().

◆ GetSESSION()

SESSION * DSN::SPECCTRA_DB::GetSESSION ( )
inline

Definition at line 3705 of file specctra.h.

3705{ return m_session; }

References m_session.

Referenced by main().

◆ LoadPCB()

void DSN::SPECCTRA_DB::LoadPCB ( const wxString &  aFilename)

A recursive descent parser for a SPECCTRA DSN "design" file.

A design file is nearly a full description of a PCB (seems to be missing only the silkscreen stuff).

Parameters
aFilenameThe name of the dsn file to load.
Exceptions
IO_ERRORif there is a lexer or parser error.

Definition at line 258 of file specctra.cpp.

259{
260 FILE_LINE_READER curr_reader( aFilename );
261
262 PushReader( &curr_reader );
263
264 if( NextTok() != T_LEFT )
265 Expecting( T_LEFT );
266
267 if( NextTok() != T_pcb )
268 Expecting( T_pcb );
269
270 SetPCB( new PCB() );
271
272 doPCB( m_pcb );
273 PopReader();
274}
void doPCB(PCB *growth)
Definition: specctra.cpp:297
void SetPCB(PCB *aPcb)
Delete any existing PCB and replaces it with the given one.
Definition: specctra.h:3688
A LINE_READER that reads from an open file.
Definition: richio.h:173

References doPCB(), m_pcb, and SetPCB().

◆ LoadSESSION()

void DSN::SPECCTRA_DB::LoadSESSION ( const wxString &  aFilename)

A recursive descent parser for a SPECCTRA DSN "session" file.

A session file is a file that is fed back from the router to the layout tool (Pcbnew) and should be used to update a BOARD object with the new tracks, vias, and component locations.

Parameters
aFilenameThe name of the dsn file to load.
Exceptions
IO_ERRORif there is a lexer or parser error.

Definition at line 277 of file specctra.cpp.

278{
279 FILE_LINE_READER curr_reader( aFilename );
280
281 PushReader( &curr_reader );
282
283 if( NextTok() != T_LEFT )
284 Expecting( T_LEFT );
285
286 if( NextTok() != T_session )
287 Expecting( T_session );
288
289 SetSESSION( new SESSION() );
290
292
293 PopReader();
294}
void SetSESSION(SESSION *aSession)
Delete any existing SESSION and replaces it with the given one.
Definition: specctra.h:3699
void doSESSION(SESSION *growth)
Definition: specctra.cpp:3373

References doSESSION(), m_session, and SetSESSION().

Referenced by PCB_EDIT_FRAME::ImportSpecctraSession(), and main().

◆ makeIMAGE()

IMAGE * DSN::SPECCTRA_DB::makeIMAGE ( BOARD aBoard,
FOOTPRINT aFootprint 
)
private

Allocates an I::MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT.

Parameters
aBoardThe owner of the FOOTPRINT.
aFootprintThe FOOTPRINT from which to build the IMAGE.
Returns
not tested for duplication yet.

Definition at line 599 of file specctra_export.cpp.

600{
601 PINMAP pinmap;
602 wxString padNumber;
603
604 PCB_TYPE_COLLECTOR fpItems;
605
606 // get all the FOOTPRINT's pads.
607 fpItems.Collect( aFootprint, { PCB_PAD_T } );
608
609 IMAGE* image = new IMAGE( 0 );
610
611 image->image_id = aFootprint->GetFPID().Format().c_str();
612
613 // from the pads, and make an IMAGE using collated padstacks.
614 for( int p = 0; p < fpItems.GetCount(); ++p )
615 {
616 PAD* pad = (PAD*) fpItems[p];
617
618 // see if this pad is a through hole with no copper on its perimeter
619 if( isRoundKeepout( pad ) )
620 {
621 double diameter = scale( pad->GetDrillSize().x );
622 POINT vertex = mapPt( pad->GetPos0() );
623
624 int layerCount = aBoard->GetCopperLayerCount();
625
626 for( int layer=0; layer<layerCount; ++layer )
627 {
628 KEEPOUT* keepout = new KEEPOUT( image, T_keepout );
629
630 image->keepouts.push_back( keepout );
631
632 CIRCLE* circle = new CIRCLE( keepout );
633
634 keepout->SetShape( circle );
635
636 circle->SetDiameter( diameter );
637 circle->SetVertex( vertex );
638 circle->SetLayerId( m_layerIds[layer].c_str() );
639 }
640 }
641 else // else if() could there be a square keepout here?
642 {
643 // Pads not on copper layers (i.e. only on tech layers) are ignored
644 // because they create invalid pads in .dsn file for freeroute
645 LSET mask_copper_layers = pad->GetLayerSet() & LSET::AllCuMask();
646
647 if( !mask_copper_layers.any() )
648 continue;
649
650 PADSTACK* padstack = makePADSTACK( aBoard, pad );
651 PADSTACKSET::iterator iter = m_padstackset.find( *padstack );
652
653 if( iter != m_padstackset.end() )
654 {
655 // padstack is a duplicate, delete it and use the original
656 delete padstack;
657 padstack = (PADSTACK*) *iter.base(); // folklore, be careful here
658 }
659 else
660 {
661 m_padstackset.insert( padstack );
662 }
663
664 PIN* pin = new PIN( image );
665
666 padNumber = pad->GetNumber();
667 pin->pin_id = TO_UTF8( padNumber );
668
669 if( padNumber != wxEmptyString && pinmap.find( padNumber ) == pinmap.end() )
670 {
671 pinmap[ padNumber ] = 0;
672 }
673 else // pad name is a duplicate within this footprint
674 {
675 char buf[32];
676 int duplicates = ++pinmap[ padNumber ];
677
678 sprintf( buf, "@%d", duplicates );
679
680 pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
681 }
682
683 pin->kiNetCode = pad->GetNetCode();
684
685 image->pins.push_back( pin );
686
687 pin->padstack_id = padstack->padstack_id;
688
689 EDA_ANGLE angle = pad->GetOrientation() - aFootprint->GetOrientation();
690 pin->SetRotation( angle.Normalize().AsDegrees() );
691
692 wxPoint pos( pad->GetPos0() );
693
694 pin->SetVertex( mapPt( pos ) );
695 }
696 }
697
698 // get all the FOOTPRINT's FP_SHAPEs and convert those to DSN outlines.
699 fpItems.Collect( aFootprint, { PCB_FP_SHAPE_T } );
700
701 for( int i = 0; i < fpItems.GetCount(); ++i )
702 {
703 FP_SHAPE* graphic = (FP_SHAPE*) fpItems[i];
704 SHAPE* outline;
705 PATH* path;
706
707 switch( graphic->GetShape() )
708 {
709 case SHAPE_T::SEGMENT:
710 outline = new SHAPE( image, T_outline );
711
712 image->Append( outline );
713 path = new PATH( outline );
714
715 outline->SetShape( path );
716 path->SetAperture( scale( graphic->GetWidth() ) );
717 path->SetLayerId( "signal" );
718 path->AppendPoint( mapPt( graphic->GetStart0() ) );
719 path->AppendPoint( mapPt( graphic->GetEnd0() ) );
720 break;
721
722 case SHAPE_T::CIRCLE:
723 {
724 // this is best done by 4 QARC's but freerouter does not yet support QARCs.
725 // for now, support by using line segments.
726 outline = new SHAPE( image, T_outline );
727 image->Append( outline );
728
729 path = new PATH( outline );
730
731 outline->SetShape( path );
732 path->SetAperture( scale( graphic->GetWidth() ) );
733 path->SetLayerId( "signal" );
734
735 double radius = graphic->GetRadius();
736 VECTOR2I circle_centre = graphic->GetStart0();
737
738 SHAPE_LINE_CHAIN polyline;
739 ConvertArcToPolyline( polyline, VECTOR2I( circle_centre ), radius, ANGLE_0, ANGLE_360,
741
742 for( int ii = 0; ii < polyline.PointCount(); ++ii )
743 {
744 VECTOR2I corner( polyline.CPoint( ii ).x, polyline.CPoint( ii ).y );
745 path->AppendPoint( mapPt( corner ) );
746 }
747
748 break;
749 }
750
751 case SHAPE_T::RECT:
752 {
753 outline = new SHAPE( image, T_outline );
754
755 image->Append( outline );
756 path = new PATH( outline );
757
758 outline->SetShape( path );
759 path->SetAperture( scale( graphic->GetWidth() ) );
760 path->SetLayerId( "signal" );
761 VECTOR2I corner = graphic->GetStart0();
762 path->AppendPoint( mapPt( corner ) );
763
764 corner.x = graphic->GetEnd0().x;
765 path->AppendPoint( mapPt( corner ) );
766
767 corner.y = graphic->GetEnd0().y;
768 path->AppendPoint( mapPt( corner ) );
769
770 corner.x = graphic->GetStart0().x;
771 path->AppendPoint( mapPt( corner ) );
772 break;
773 }
774
775 case SHAPE_T::ARC:
776 {
777 // this is best done by QARC's but freerouter does not yet support QARCs.
778 // for now, support by using line segments.
779 // So we use a polygon (PATH) to create a approximate arc shape
780 outline = new SHAPE( image, T_outline );
781
782 image->Append( outline );
783 path = new PATH( outline );
784
785 outline->SetShape( path );
786 path->SetAperture( 0 );//scale( graphic->GetWidth() ) );
787 path->SetLayerId( "signal" );
788
789 VECTOR2I arc_centre = graphic->GetCenter0();
790 double radius = graphic->GetRadius() + graphic->GetWidth()/2;
791 EDA_ANGLE arcAngle = graphic->GetArcAngle();
792
793 VECTOR2I startRadial = graphic->GetStart() - graphic->GetCenter();
794 EDA_ANGLE arcStart( startRadial );
795
796 arcStart.Normalize();
797
798 // For some obscure reason, FreeRouter does not show the same polygonal
799 // shape for polygons CW and CCW. So used only the order of corners
800 // giving the best look.
801 if( arcAngle < ANGLE_0 )
802 {
803 VECTOR2I endRadial = graphic->GetEnd() - graphic->GetCenter();
804 arcStart = EDA_ANGLE( endRadial );
805 arcStart.Normalize();
806
807 arcAngle = -arcAngle;
808 }
809
810 SHAPE_LINE_CHAIN polyline;
811 ConvertArcToPolyline( polyline, VECTOR2I( arc_centre ), radius, arcStart, arcAngle,
813
814 SHAPE_POLY_SET polyBuffer;
815 polyBuffer.AddOutline( polyline );
816
817 radius -= graphic->GetWidth();
818
819 if( radius > 0 )
820 {
821 polyline.Clear();
822 ConvertArcToPolyline( polyline, VECTOR2I( arc_centre ), radius, arcStart, arcAngle,
824
825 // Add points in reverse order, to create a closed polygon
826 for( int ii = polyline.PointCount() - 1; ii >= 0; --ii )
827 polyBuffer.Append( polyline.CPoint( ii ) );
828 }
829
830 // ensure the polygon is closed
831 polyBuffer.Append( polyBuffer.Outline( 0 ).CPoint( 0 ) );
832
833 VECTOR2I move = graphic->GetCenter() - arc_centre;
834
835 TransformCircleToPolygon( polyBuffer, graphic->GetStart() - move,
836 graphic->GetWidth() / 2, ARC_HIGH_DEF, ERROR_INSIDE );
837
838 TransformCircleToPolygon( polyBuffer, graphic->GetEnd() - move,
839 graphic->GetWidth() / 2, ARC_HIGH_DEF, ERROR_INSIDE );
840
841 polyBuffer.Simplify( SHAPE_POLY_SET::PM_FAST );
842 SHAPE_LINE_CHAIN& poly = polyBuffer.Outline( 0 );
843
844 for( int ii = 0; ii < poly.PointCount(); ++ii )
845 {
846 VECTOR2I corner( poly.CPoint( ii ).x, poly.CPoint( ii ).y );
847 path->AppendPoint( mapPt( corner ) );
848 }
849
850 break;
851 }
852
853 default:
854 continue;
855 }
856 }
857
858 for( FP_ZONE* zone : aFootprint->Zones() )
859 {
860 if( !zone->GetIsRuleArea() )
861 continue;
862
863 // IMAGE object coordinates are relative to the IMAGE not absolute board coordinates.
864 ZONE untransformedZone( *zone );
865
866 EDA_ANGLE angle = -aFootprint->GetOrientation();
867 angle.Normalize();
868 untransformedZone.Rotate( aFootprint->GetPosition(), angle );
869
870 // keepout areas have a type. types are
871 // T_place_keepout, T_via_keepout, T_wire_keepout,
872 // T_bend_keepout, T_elongate_keepout, T_keepout.
873 // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
874 DSN_T keepout_type;
875
876 if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
877 keepout_type = T_keepout;
878 else if( zone->GetDoNotAllowVias() )
879 keepout_type = T_via_keepout;
880 else if( zone->GetDoNotAllowTracks() )
881 keepout_type = T_wire_keepout;
882 else
883 keepout_type = T_keepout;
884
885 // Now, build keepout polygon on each copper layer where the zone
886 // keepout is living (keepout zones can live on many copper layers)
887 const int copperCount = aBoard->GetCopperLayerCount();
888
889 for( int layer = 0; layer < copperCount; layer++ )
890 {
891 if( layer == copperCount-1 )
892 layer = B_Cu;
893
894 if( !zone->IsOnLayer( PCB_LAYER_ID( layer ) ) )
895 continue;
896
897 KEEPOUT* keepout = new KEEPOUT( m_pcb->structure, keepout_type );
898 image->keepouts.push_back( keepout );
899
900 PATH* mainPolygon = new PATH( keepout, T_polygon );
901 keepout->SetShape( mainPolygon );
902
903 mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
904
905 // Handle the main outlines
907 bool is_first_point = true;
908 VECTOR2I startpoint;
909
910 for( iterator = untransformedZone.IterateWithHoles(); iterator; iterator++ )
911 {
912 VECTOR2I point( iterator->x, iterator->y );
913
914 point -= aFootprint->GetPosition();
915
916 if( is_first_point )
917 {
918 startpoint = point;
919 is_first_point = false;
920 }
921
922 mainPolygon->AppendPoint( mapPt( point ) );
923
924 // this was the end of the main polygon
925 if( iterator.IsEndContour() )
926 {
927 mainPolygon->AppendPoint( mapPt( startpoint ) );
928 break;
929 }
930 }
931
932 WINDOW* window = nullptr;
933 PATH* cutout = nullptr;
934 bool isStartContour = true;
935
936 // handle the cutouts
937 for( iterator++; iterator; iterator++ )
938 {
939 if( isStartContour )
940 {
941 is_first_point = true;
942 window = new WINDOW( keepout );
943 keepout->AddWindow( window );
944
945 cutout = new PATH( window, T_polygon );
946
947 window->SetShape( cutout );
948
949 cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ];
950 }
951
952 isStartContour = iterator.IsEndContour();
953
954 wxASSERT( window );
955 wxASSERT( cutout );
956
957 VECTOR2I point( iterator->x, iterator->y );
958
959 point -= aFootprint->GetPosition();
960
961 if( is_first_point )
962 {
963 startpoint = point;
964 is_first_point = false;
965 }
966
967 cutout->AppendPoint( mapPt( point ) );
968
969 // Close the polygon
970 if( iterator.IsEndContour() )
971 cutout->AppendPoint( mapPt( startpoint ) );
972 }
973 }
974 }
975
976 return image;
977}
constexpr int ARC_HIGH_DEF
Definition: base_units.h:121
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
void SetLayerId(const char *aLayerId)
Definition: specctra.h:757
void SetVertex(const POINT &aVertex)
Definition: specctra.h:767
void SetDiameter(double aDiameter)
Definition: specctra.h:762
std::string padstack_id
Definition: specctra.h:2226
A "(shape ..)" element in the specctra dsn spec.
Definition: specctra.h:1894
PADSTACK * makePADSTACK(BOARD *aBoard, PAD *aPad)
Create a #PADSTACK which matches the given pad.
EDA_ANGLE GetArcAngle() const
Definition: eda_shape.cpp:538
int GetRadius() const
Definition: eda_shape.cpp:476
SHAPE_T GetShape() const
Definition: eda_shape.h:111
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:141
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:116
int GetWidth() const
Definition: eda_shape.h:107
EDA_ANGLE GetOrientation() const
Definition: footprint.h:195
const LIB_ID & GetFPID() const
Definition: footprint.h:207
FP_ZONES & Zones()
Definition: footprint.h:180
const VECTOR2I & GetEnd0() const
Definition: fp_shape.h:95
VECTOR2I GetCenter0() const
Definition: fp_shape.cpp:144
const VECTOR2I & GetStart0() const
Definition: fp_shape.h:92
A specialization of ZONE for use in footprints.
Definition: zone.h:897
UTF8 Format() const
Definition: lib_id.cpp:117
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
Definition: pad.h:58
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:65
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition: collectors.h:522
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Collect BOARD_ITEM objects using this class's Inspector method, which does the collection.
Definition: collectors.cpp:631
void Clear()
Remove all points from the line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
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...
void Simplify(POLYGON_MODE aFastMode)
const char * c_str() const
Definition: utf8.h:102
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aCornerBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
int ConvertArcToPolyline(SHAPE_LINE_CHAIN &aPolyline, VECTOR2I aCenter, int aRadius, const EDA_ANGLE &aStartAngleDeg, const EDA_ANGLE &aArcAngleDeg, double aAccuracy, ERROR_LOC aErrorLoc)
Generate a polyline to approximate a arc.
static constexpr EDA_ANGLE & ANGLE_360
Definition: eda_angle.h:418
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:412
@ ERROR_INSIDE
std::map< wxString, int > PINMAP
data type used to ensure unique-ness of pin names, holding (wxString and int)
static bool isRoundKeepout(PAD *aPad)
Decide if the pad is a copper-less through hole which needs to be made into a round keepout.
A point in the SPECCTRA DSN coordinate system.
Definition: specctra.h:103
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References SHAPE_POLY_SET::AddOutline(), DSN::KEEPOUT::AddWindow(), LSET::AllCuMask(), PNS::angle(), ANGLE_0, ANGLE_360, SHAPE_POLY_SET::Append(), DSN::PATH::AppendPoint(), ARC, ARC_HIGH_DEF, B_Cu, UTF8::c_str(), CIRCLE, SHAPE_LINE_CHAIN::Clear(), PCB_TYPE_COLLECTOR::Collect(), ConvertArcToPolyline(), SHAPE_LINE_CHAIN::CPoint(), ERROR_INSIDE, LIB_ID::Format(), EDA_SHAPE::GetArcAngle(), PCB_SHAPE::GetCenter(), FP_SHAPE::GetCenter0(), BOARD::GetCopperLayerCount(), COLLECTOR::GetCount(), EDA_SHAPE::GetEnd(), FP_SHAPE::GetEnd0(), FOOTPRINT::GetFPID(), FOOTPRINT::GetOrientation(), FOOTPRINT::GetPosition(), EDA_SHAPE::GetRadius(), EDA_SHAPE::GetShape(), EDA_SHAPE::GetStart(), FP_SHAPE::GetStart0(), EDA_SHAPE::GetWidth(), image, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), DSN::isRoundKeepout(), ZONE::IterateWithHoles(), DSN::PATH::layer_id, m_kicadLayer2pcb, m_layerIds, m_padstackset, m_pcb, makePADSTACK(), DSN::mapPt(), move, EDA_ANGLE::Normalize(), SHAPE_POLY_SET::Outline(), pad, DSN::PADSTACK::padstack_id, path, PCB_FP_SHAPE_T, PCB_PAD_T, pin, SHAPE_POLY_SET::PM_FAST, SHAPE_LINE_CHAIN::PointCount(), RECT, ZONE::Rotate(), DSN::scale(), SEGMENT, DSN::CIRCLE::SetDiameter(), DSN::CIRCLE::SetLayerId(), DSN::WINDOW::SetShape(), DSN::KEEPOUT::SetShape(), DSN::CIRCLE::SetVertex(), SHAPE_POLY_SET::Simplify(), DSN::PCB::structure, TO_UTF8, TransformCircleToPolygon(), VECTOR2< T >::x, VECTOR2< T >::y, and FOOTPRINT::Zones().

Referenced by FromBOARD().

◆ makePADSTACK()

PADSTACK * DSN::SPECCTRA_DB::makePADSTACK ( BOARD aBoard,
PAD aPad 
)
private

Create a #PADSTACK which matches the given pad.

Note
Only pads which do not satisfy the function isKeepout() should be passed to this function.
Parameters
aBoardThe owner of the PAD's footprint.
aPadThe PAD which needs to be made into a PADSTACK.
Returns
The created padstack, including its padstack_id.

Definition at line 238 of file specctra_export.cpp.

239{
240 char name[256]; // padstack name builder
241 std::string uniqifier;
242
243 // caller must do these checks before calling here.
244 wxASSERT( !isRoundKeepout( aPad ) );
245
246 PADSTACK* padstack = new PADSTACK();
247
248 int reportedLayers = 0; // how many in reported padstack
249 const char* layerName[MAX_CU_LAYERS];
250
251 uniqifier = '[';
252
253 static const LSET all_cu = LSET::AllCuMask();
254
255 bool onAllCopperLayers = ( (aPad->GetLayerSet() & all_cu) == all_cu );
256
257 if( onAllCopperLayers )
258 uniqifier += 'A'; // A for all layers
259
260 const int copperCount = aBoard->GetCopperLayerCount();
261
262 for( int layer=0; layer<copperCount; ++layer )
263 {
264 PCB_LAYER_ID kilayer = m_pcbLayer2kicad[layer];
265
266 if( onAllCopperLayers || aPad->IsOnLayer( kilayer ) )
267 {
268 layerName[reportedLayers++] = m_layerIds[layer].c_str();
269
270 if( !onAllCopperLayers )
271 {
272 if( layer == 0 )
273 uniqifier += 'T';
274 else if( layer == copperCount - 1 )
275 uniqifier += 'B';
276 else
277 uniqifier += char('0' + layer); // layer index char
278 }
279 }
280 }
281
282 uniqifier += ']';
283
284 POINT dsnOffset;
285
286 if( aPad->GetOffset().x || aPad->GetOffset().y )
287 {
288 char offsetTxt[64];
289
290 VECTOR2I offset( aPad->GetOffset().x, aPad->GetOffset().y );
291
292 dsnOffset = mapPt( offset );
293
294 // using () would cause padstack name to be quoted, and {} locks freerouter, so use [].
295 sprintf( offsetTxt, "[%.6g,%.6g]", dsnOffset.x, dsnOffset.y );
296
297 uniqifier += offsetTxt;
298 }
299
300 switch( aPad->GetShape() )
301 {
303 {
304 double diameter = scale( aPad->GetSize().x );
305
306 for( int ndx = 0; ndx < reportedLayers; ++ndx )
307 {
308 SHAPE* shape = new SHAPE( padstack );
309
310 padstack->Append( shape );
311
312 CIRCLE* circle = new CIRCLE( shape );
313
314 shape->SetShape( circle );
315
316 circle->SetLayerId( layerName[ndx] );
317 circle->SetDiameter( diameter );
318 circle->SetVertex( dsnOffset );
319 }
320
321 snprintf( name, sizeof(name), "Round%sPad_%.6g_um",
322 uniqifier.c_str(), IU2um( aPad->GetSize().x ) );
323
324 name[ sizeof(name) - 1 ] = 0;
325
326 padstack->SetPadstackId( name );
327 break;
328 }
329
330 case PAD_SHAPE::RECT:
331 {
332 double dx = scale( aPad->GetSize().x ) / 2.0;
333 double dy = scale( aPad->GetSize().y ) / 2.0;
334
335 POINT lowerLeft( -dx, -dy );
336 POINT upperRight( dx, dy );
337
338 lowerLeft += dsnOffset;
339 upperRight += dsnOffset;
340
341 for( int ndx = 0; ndx < reportedLayers; ++ndx )
342 {
343 SHAPE* shape = new SHAPE( padstack );
344
345 padstack->Append( shape );
346
347 RECTANGLE* rect = new RECTANGLE( shape );
348
349 shape->SetShape( rect );
350
351 rect->SetLayerId( layerName[ndx] );
352 rect->SetCorners( lowerLeft, upperRight );
353 }
354
355 snprintf( name, sizeof( name ), "Rect%sPad_%.6gx%.6g_um", uniqifier.c_str(),
356 IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ) );
357
358 name[sizeof( name ) - 1] = 0;
359
360 padstack->SetPadstackId( name );
361 break;
362 }
363
364 case PAD_SHAPE::OVAL:
365 {
366 double dx = scale( aPad->GetSize().x ) / 2.0;
367 double dy = scale( aPad->GetSize().y ) / 2.0;
368 double dr = dx - dy;
369 double radius;
370 POINT pstart;
371 POINT pstop;
372
373 if( dr >= 0 ) // oval is horizontal
374 {
375 radius = dy;
376
377 pstart = POINT( -dr, 0.0 );
378 pstop = POINT( dr, 0.0 );
379 }
380 else // oval is vertical
381 {
382 radius = dx;
383 dr = -dr;
384
385 pstart = POINT( 0.0, -dr );
386 pstop = POINT( 0.0, dr );
387 }
388
389 pstart += dsnOffset;
390 pstop += dsnOffset;
391
392 for( int ndx = 0; ndx < reportedLayers; ++ndx )
393 {
394 SHAPE* shape;
395 PATH* path;
396
397 // see http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
398 shape = new SHAPE( padstack );
399
400 padstack->Append( shape );
401 path = makePath( pstart, pstop, layerName[ndx] );
402 shape->SetShape( path );
403 path->aperture_width = 2.0 * radius;
404 }
405
406 snprintf( name, sizeof( name ), "Oval%sPad_%.6gx%.6g_um", uniqifier.c_str(),
407 IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ) );
408 name[sizeof( name ) - 1] = 0;
409
410 padstack->SetPadstackId( name );
411 break;
412 }
413
415 {
416 double dx = scale( aPad->GetSize().x ) / 2.0;
417 double dy = scale( aPad->GetSize().y ) / 2.0;
418
419 double ddx = scale( aPad->GetDelta().x ) / 2.0;
420 double ddy = scale( aPad->GetDelta().y ) / 2.0;
421
422 // see class_pad_draw_functions.cpp which draws the trapezoid pad
423 POINT lowerLeft( -dx - ddy, -dy - ddx );
424 POINT upperLeft( -dx + ddy, +dy + ddx );
425 POINT upperRight( +dx - ddy, +dy - ddx );
426 POINT lowerRight( +dx + ddy, -dy + ddx );
427
428 lowerLeft += dsnOffset;
429 upperLeft += dsnOffset;
430 upperRight += dsnOffset;
431 lowerRight += dsnOffset;
432
433 for( int ndx = 0; ndx < reportedLayers; ++ndx )
434 {
435 SHAPE* shape = new SHAPE( padstack );
436
437 padstack->Append( shape );
438
439 // a T_polygon exists as a PATH
440 PATH* polygon = new PATH( shape, T_polygon );
441
442 shape->SetShape( polygon );
443
444 polygon->SetLayerId( layerName[ndx] );
445
446 polygon->AppendPoint( lowerLeft );
447 polygon->AppendPoint( upperLeft );
448 polygon->AppendPoint( upperRight );
449 polygon->AppendPoint( lowerRight );
450 }
451
452 // this string _must_ be unique for a given physical shape
453 snprintf( name, sizeof( name ), "Trapz%sPad_%.6gx%.6g_%c%.6gx%c%.6g_um", uniqifier.c_str(),
454 IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ),
455 aPad->GetDelta().x < 0 ? 'n' : 'p', std::abs( IU2um( aPad->GetDelta().x ) ),
456 aPad->GetDelta().y < 0 ? 'n' : 'p', std::abs( IU2um( aPad->GetDelta().y ) ) );
457 name[sizeof( name ) - 1] = 0;
458
459 padstack->SetPadstackId( name );
460 break;
461 }
462
465 {
466 // Export the shape as as polygon, round rect does not exist as primitive
467 const int circleToSegmentsCount = 36;
468 int rradius = aPad->GetRoundRectCornerRadius();
469 SHAPE_POLY_SET cornerBuffer;
470
471 // Use a slightly bigger shape because the round corners are approximated by
472 // segments, giving to the polygon a slightly smaller shape than the actual shape
473
474 /* calculates the coeff to compensate radius reduction of holes clearance
475 * due to the segment approx.
476 * For a circle the min radius is radius * cos( 2PI / s_CircleToSegmentsCount / 2)
477 * correctionFactor is cos( PI/s_CircleToSegmentsCount )
478 */
479 double correctionFactor = cos( M_PI / (double) circleToSegmentsCount );
480 int extra_clearance = KiROUND( rradius * ( 1.0 - correctionFactor ) );
481 VECTOR2I psize = aPad->GetSize();
482 psize.x += extra_clearance * 2;
483 psize.y += extra_clearance * 2;
484 rradius += extra_clearance;
485 bool doChamfer = aPad->GetShape() == PAD_SHAPE::CHAMFERED_RECT;
486
487 TransformRoundChamferedRectToPolygon( cornerBuffer, VECTOR2I( 0, 0 ), psize, ANGLE_0,
488 rradius, aPad->GetChamferRectRatio(),
489 doChamfer ? aPad->GetChamferPositions() : 0,
490 0, aBoard->GetDesignSettings().m_MaxError,
491 ERROR_INSIDE );
492
493 SHAPE_LINE_CHAIN& polygonal_shape = cornerBuffer.Outline( 0 );
494
495 for( int ndx = 0; ndx < reportedLayers; ++ndx )
496 {
497 SHAPE* shape = new SHAPE( padstack );
498
499 padstack->Append( shape );
500
501 // a T_polygon exists as a PATH
502 PATH* polygon = new PATH( shape, T_polygon );
503
504 shape->SetShape( polygon );
505
506 polygon->SetLayerId( layerName[ndx] );
507
508 // append a closed polygon
509 POINT first_corner;
510
511 for( int idx = 0; idx < polygonal_shape.PointCount(); idx++ )
512 {
513 POINT corner( scale( polygonal_shape.CPoint( idx ).x ),
514 scale( -polygonal_shape.CPoint( idx ).y ) );
515 corner += dsnOffset;
516 polygon->AppendPoint( corner );
517
518 if( idx == 0 )
519 first_corner = corner;
520 }
521
522 polygon->AppendPoint( first_corner ); // Close polygon
523 }
524
525 // this string _must_ be unique for a given physical shape
526 snprintf( name, sizeof( name ), "RoundRect%sPad_%.6gx%.6g_%.6g_um_%f_%X", uniqifier.c_str(),
527 IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ), IU2um( rradius ),
528 doChamfer ? aPad->GetChamferRectRatio() : 0.0,
529 doChamfer ? aPad->GetChamferPositions() : 0 );
530
531 name[sizeof( name ) - 1] = 0;
532
533 padstack->SetPadstackId( name );
534 break;
535 }
536
538 {
539 std::vector<VECTOR2I> polygonal_shape;
540 SHAPE_POLY_SET pad_shape;
541 aPad->MergePrimitivesAsPolygon( &pad_shape );
542
543#ifdef EXPORT_CUSTOM_PADS_CONVEX_HULL
544 BuildConvexHull( polygonal_shape, pad_shape );
545#else
546 const SHAPE_LINE_CHAIN& p_outline = pad_shape.COutline( 0 );
547
548 for( int ii = 0; ii < p_outline.PointCount(); ++ii )
549 polygonal_shape.push_back( wxPoint( p_outline.CPoint( ii ) ) );
550#endif
551
552 // The polygon must be closed
553 if( polygonal_shape.front() != polygonal_shape.back() )
554 polygonal_shape.push_back( polygonal_shape.front() );
555
556 for( int ndx = 0; ndx < reportedLayers; ++ndx )
557 {
558 SHAPE* shape = new SHAPE( padstack );
559
560 padstack->Append( shape );
561
562 // a T_polygon exists as a PATH
563 PATH* polygon = new PATH( shape, T_polygon );
564
565 shape->SetShape( polygon );
566
567 polygon->SetLayerId( layerName[ndx] );
568
569 for( unsigned idx = 0; idx < polygonal_shape.size(); idx++ )
570 {
571 POINT corner( scale( polygonal_shape[idx].x ), scale( -polygonal_shape[idx].y ) );
572 corner += dsnOffset;
573 polygon->AppendPoint( corner );
574 }
575 }
576
577 // this string _must_ be unique for a given physical shape, so try to make it unique
578 MD5_HASH hash = pad_shape.GetHash();
579 BOX2I rect = aPad->GetBoundingBox();
580 snprintf( name, sizeof( name ), "Cust%sPad_%.6gx%.6g_%.6gx_%.6g_%d_um_%s",
581 uniqifier.c_str(), IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ),
582 IU2um( rect.GetWidth() ), IU2um( rect.GetHeight() ), (int) polygonal_shape.size(),
583 hash.Format( true ).c_str() );
584 name[sizeof( name ) - 1] = 0;
585
586 padstack->SetPadstackId( name );
587 break;
588 }
589 }
590
591 return padstack;
592}
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetWidth() const
Definition: box2.h:187
void Append(ELEM *aElem)
Definition: specctra.h:322
void SetPadstackId(const char *aPadstackId)
Definition: specctra.h:2160
void SetCorners(const POINT &aPoint0, const POINT &aPoint1)
Definition: specctra.h:452
void SetLayerId(const char *aLayerId)
Definition: specctra.h:447
std::string Format(bool aCompactForm=false)
Definition: md5_hash.cpp:97
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:391
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
Definition: pad.cpp:613
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pad.h:600
void MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
int GetRoundRectCornerRadius() const
Definition: pad.cpp:307
const VECTOR2I & GetOffset() const
Definition: pad.h:268
const VECTOR2I & GetDelta() const
Definition: pad.h:258
PAD_SHAPE GetShape() const
Definition: pad.h:188
int GetChamferPositions() const
Definition: pad.h:575
const VECTOR2I & GetSize() const
Definition: pad.h:251
double GetChamferRectRatio() const
Definition: pad.h:565
MD5_HASH GetHash() const
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
Definition: convex_hull.cpp:87
#define MAX_CU_LAYERS
Definition: layer_ids.h:140
static double IU2um(int kicadDist)
static PATH * makePath(const POINT &aStart, const POINT &aEnd, const std::string &aLayerName)
Create a PATH element with a single straight line, a pair of vertices.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401
double y
Definition: specctra.h:105
double x
Definition: specctra.h:104
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 std::abs(), LSET::AllCuMask(), ANGLE_0, DSN::ELEM_HOLDER::Append(), DSN::PATH::AppendPoint(), BuildConvexHull(), CHAMFERED_RECT, CIRCLE, SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), CUSTOM, ERROR_INSIDE, MD5_HASH::Format(), PAD::GetBoundingBox(), PAD::GetChamferPositions(), PAD::GetChamferRectRatio(), BOARD::GetCopperLayerCount(), PAD::GetDelta(), BOARD::GetDesignSettings(), SHAPE_POLY_SET::GetHash(), BOX2< Vec >::GetHeight(), PAD::GetLayerSet(), PAD::GetOffset(), PAD::GetRoundRectCornerRadius(), PAD::GetShape(), PAD::GetSize(), BOX2< Vec >::GetWidth(), PAD::IsOnLayer(), DSN::isRoundKeepout(), DSN::IU2um(), KiROUND(), m_layerIds, BOARD_DESIGN_SETTINGS::m_MaxError, m_pcbLayer2kicad, DSN::makePath(), DSN::mapPt(), MAX_CU_LAYERS, PAD::MergePrimitivesAsPolygon(), name, SHAPE_POLY_SET::Outline(), OVAL, path, SHAPE_LINE_CHAIN::PointCount(), RECT, ROUNDRECT, DSN::scale(), DSN::RECTANGLE::SetCorners(), DSN::CIRCLE::SetDiameter(), DSN::RECTANGLE::SetLayerId(), DSN::PATH::SetLayerId(), DSN::CIRCLE::SetLayerId(), DSN::PADSTACK::SetPadstackId(), DSN::WINDOW::SetShape(), DSN::CIRCLE::SetVertex(), TransformRoundChamferedRectToPolygon(), TRAPEZOID, VECTOR2< T >::x, DSN::POINT::x, VECTOR2< T >::y, and DSN::POINT::y.

Referenced by makeIMAGE().

◆ MakePCB()

PCB * DSN::SPECCTRA_DB::MakePCB ( )
static

Make a PCB with all the default ELEMs and parts on the heap.

Definition at line 3722 of file specctra.cpp.

3723{
3724 PCB* pcb = new PCB();
3725
3726 pcb->parser = new PARSER( pcb );
3727 pcb->resolution = new UNIT_RES( pcb, T_resolution );
3728 pcb->unit = new UNIT_RES( pcb, T_unit );
3729
3730 pcb->structure = new STRUCTURE( pcb );
3731 pcb->structure->boundary = new BOUNDARY( pcb->structure );
3732 pcb->structure->via = new VIA( pcb->structure );
3733 pcb->structure->rules = new RULE( pcb->structure, T_rule );
3734
3735 pcb->placement = new PLACEMENT( pcb );
3736
3737 pcb->library = new LIBRARY( pcb );
3738
3739 pcb->network = new NETWORK( pcb );
3740
3741 pcb->wiring = new WIRING( pcb );
3742
3743 return pcb;
3744}

References DSN::STRUCTURE::boundary, DSN::PCB::library, DSN::PCB::network, DSN::PCB::parser, DSN::PCB::placement, DSN::PCB::resolution, RULE, DSN::STRUCTURE::rules, DSN::PCB::structure, DSN::PCB::unit, VIA, DSN::STRUCTURE::via, and DSN::PCB::wiring.

Referenced by FromBOARD().

◆ makeTRACK()

PCB_TRACK * DSN::SPECCTRA_DB::makeTRACK ( WIRE wire,
PATH aPath,
int  aPointIndex,
int  aNetcode 
)
private

Create a #TRACK form the #PATH and BOARD info.

Definition at line 153 of file specctra_import.cpp.

154{
155 int layerNdx = findLayerName( aPath->layer_id );
156
157 if( layerNdx == -1 )
158 {
159 THROW_IO_ERROR( wxString::Format( _( "Session file uses invalid layer id '%s'." ),
160 FROM_UTF8( aPath->layer_id.c_str() ) ) );
161 }
162
163 PCB_TRACK* track = new PCB_TRACK( m_sessionBoard );
164
165 track->SetStart( mapPt( aPath->points[aPointIndex+0], m_routeResolution ) );
166 track->SetEnd( mapPt( aPath->points[aPointIndex+1], m_routeResolution ) );
167 track->SetLayer( m_pcbLayer2kicad[layerNdx] );
168 track->SetWidth( scale( aPath->aperture_width, m_routeResolution ) );
169 track->SetNetCode( aNetcode );
170
171 // a track can be locked.
172 // However specctra as 4 types, none is exactly the same as our locked option
173 // wire->wire_type = T_fix, T_route, T_normal or T_protect
174 // fix and protect could be used as lock option
175 // but protect is returned for all tracks having initially the route or protect property
176 if( wire->wire_type == T_fix )
177 track->SetLocked( true );
178
179 return track;
180}
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
virtual void SetLocked(bool aLocked)
Definition: board_item.h:241
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:201
POINTS points
Definition: specctra.h:653
double aperture_width
Definition: specctra.h:651
int findLayerName(const std::string &aLayerName) const
Return the PCB layer index for a given layer name, within the specctra sessionfile.
Definition: specctra.cpp:125
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

References _, DSN::PATH::aperture_width, findLayerName(), Format(), FROM_UTF8(), DSN::PATH::layer_id, m_pcbLayer2kicad, m_routeResolution, m_sessionBoard, DSN::mapPt(), DSN::PATH::points, DSN::scale(), PCB_TRACK::SetEnd(), BOARD_ITEM::SetLayer(), BOARD_ITEM::SetLocked(), BOARD_CONNECTED_ITEM::SetNetCode(), PCB_TRACK::SetStart(), PCB_TRACK::SetWidth(), THROW_IO_ERROR, and DSN::WIRE::wire_type.

Referenced by FromSESSION().

◆ makeVia() [1/2]

PADSTACK * DSN::SPECCTRA_DB::makeVia ( const ::PCB_VIA aVia)
private

Make any kind of #PADSTACK using the given KiCad #VIA.

Parameters
aViaThe #VIA to build the padstack from.
Returns
The padstack, which is on the heap only, user must save or delete it.

◆ makeVia() [2/2]

PADSTACK * DSN::SPECCTRA_DB::makeVia ( int  aCopperDiameter,
int  aDrillDiameter,
int  aTopLayer,
int  aBotLayer 
)
private

Make a round through hole #PADSTACK using the given KiCad diameter in deci-mils.

Parameters
aCopperDiameterThe diameter of the copper pad.
aDrillDiameterThe drill diameter, used on re-import of the session file.
aTopLayerThe DSN::PCB top most layer index.
aBotLayerThe DSN::PCB bottom most layer index.
Returns
The padstack, which is on the heap only, user must save or delete it.

Definition at line 980 of file specctra_export.cpp.

982{
983 char name[48];
984 PADSTACK* padstack = new PADSTACK();
985 double dsnDiameter = scale( aCopperDiameter );
986
987 for( int layer=aTopLayer; layer<=aBotLayer; ++layer )
988 {
989 SHAPE* shape = new SHAPE( padstack );
990
991 padstack->Append( shape );
992
993 CIRCLE* circle = new CIRCLE( shape );
994
995 shape->SetShape( circle );
996
997 circle->SetDiameter( dsnDiameter );
998 circle->SetLayerId( m_layerIds[layer].c_str() );
999 }
1000
1001 snprintf( name, sizeof( name ), "Via[%d-%d]_%.6g:%.6g_um",
1002 aTopLayer, aBotLayer, dsnDiameter,
1003 // encode the drill value into the name for later import
1004 IU2um( aDrillDiameter ) );
1005
1006 name[ sizeof(name) - 1 ] = 0;
1007 padstack->SetPadstackId( name );
1008
1009 return padstack;
1010}

References DSN::ELEM_HOLDER::Append(), DSN::IU2um(), m_layerIds, name, DSN::scale(), DSN::CIRCLE::SetDiameter(), DSN::CIRCLE::SetLayerId(), DSN::PADSTACK::SetPadstackId(), and DSN::WINDOW::SetShape().

Referenced by exportNETCLASS(), and FromBOARD().

◆ makeVIA()

PCB_VIA * DSN::SPECCTRA_DB::makeVIA ( WIRE_VIA aVia,
PADSTACK aPadstack,
const POINT aPoint,
int  aNetCode,
int  aViaDrillDefault 
)
private

Instantiate a KiCad #VIA on the heap and initializes it with internal values consistent with the given #PADSTACK, #POINT, and netcode.

Definition at line 183 of file specctra_import.cpp.

185{
186 PCB_VIA* via = 0;
187 SHAPE* shape;
188 int shapeCount = aPadstack->Length();
189 int drill_diam_iu = -1;
190 int copperLayerCount = m_sessionBoard->GetCopperLayerCount();
191
192
193 // The drill diameter is encoded in the padstack name if Pcbnew did the DSN export.
194 // It is after the colon and before the last '_'
195 int drillStartNdx = aPadstack->padstack_id.find( ':' );
196
197 if( drillStartNdx != -1 )
198 {
199 ++drillStartNdx; // skip over the ':'
200
201 int drillEndNdx = aPadstack->padstack_id.rfind( '_' );
202 if( drillEndNdx != -1 )
203 {
204 std::string diam_txt( aPadstack->padstack_id,
205 drillStartNdx, drillEndNdx-drillStartNdx );
206
207 double drill_um = strtod( diam_txt.c_str(), 0 );
208
209 drill_diam_iu = int( drill_um * ( pcbIUScale.IU_PER_MM / 1000.0 ) );
210
211 if( drill_diam_iu == aViaDrillDefault )
212 drill_diam_iu = UNDEFINED_DRILL_DIAMETER;
213 }
214 }
215
216 if( shapeCount == 0 )
217 {
218 THROW_IO_ERROR( _( "Session via padstack has no shapes" ) );
219 }
220 else if( shapeCount == 1 )
221 {
222 shape = (SHAPE*) (*aPadstack)[0];
223 DSN_T type = shape->shape->Type();
224
225 if( type != T_circle )
226 {
227 THROW_IO_ERROR( wxString::Format( _( "Unsupported via shape: %s." ),
228 GetTokenString( type ) ) );
229 }
230
231 CIRCLE* circle = (CIRCLE*) shape->shape;
232 int viaDiam = scale( circle->diameter, m_routeResolution );
233
234 via = new PCB_VIA( m_sessionBoard );
235 via->SetPosition( mapPt( aPoint, m_routeResolution ) );
236 via->SetDrill( drill_diam_iu );
237 via->SetViaType( VIATYPE::THROUGH );
238 via->SetWidth( viaDiam );
239 via->SetLayerPair( F_Cu, B_Cu );
240 }
241 else if( shapeCount == copperLayerCount )
242 {
243 shape = (SHAPE*) (*aPadstack)[0];
244 DSN_T type = shape->shape->Type();
245
246 if( type != T_circle )
247 {
248 THROW_IO_ERROR( wxString::Format( _( "Unsupported via shape: %s" ),
249 GetTokenString( type ) ) );
250 }
251
252 CIRCLE* circle = (CIRCLE*) shape->shape;
253 int viaDiam = scale( circle->diameter, m_routeResolution );
254
255 via = new PCB_VIA( m_sessionBoard );
256 via->SetPosition( mapPt( aPoint, m_routeResolution ) );
257 via->SetDrill( drill_diam_iu );
258 via->SetViaType( VIATYPE::THROUGH );
259 via->SetWidth( viaDiam );
260 via->SetLayerPair( F_Cu, B_Cu );
261 }
262 else // VIA_MICROVIA or VIA_BLIND_BURIED
263 {
264 int topLayerNdx = -1; // session layer detectors
265 int botLayerNdx = INT_MAX;
266
267 int viaDiam = -1;
268
269 for( int i=0; i<shapeCount; ++i )
270 {
271 shape = (SHAPE*) (*aPadstack)[i];
272 DSN_T type = shape->shape->Type();
273
274 if( type != T_circle )
275 {
276 THROW_IO_ERROR( wxString::Format( _( "Unsupported via shape: %s" ),
277 GetTokenString( type ) ) );
278 }
279
280 CIRCLE* circle = (CIRCLE*) shape->shape;
281
282 int layerNdx = findLayerName( circle->layer_id );
283 if( layerNdx == -1 )
284 {
285 wxString layerName = FROM_UTF8( circle->layer_id.c_str() );
286 THROW_IO_ERROR( wxString::Format( _( "Session file uses invalid layer id '%s'" ),
287 layerName ) );
288 }
289
290 if( layerNdx > topLayerNdx )
291 topLayerNdx = layerNdx;
292
293 if( layerNdx < botLayerNdx )
294 botLayerNdx = layerNdx;
295
296 if( viaDiam == -1 )
297 viaDiam = scale( circle->diameter, m_routeResolution );
298 }
299
300 via = new PCB_VIA( m_sessionBoard );
301 via->SetPosition( mapPt( aPoint, m_routeResolution ) );
302 via->SetDrill( drill_diam_iu );
303
304 if( ( topLayerNdx == 0 && botLayerNdx == 1 )
305 || ( topLayerNdx == copperLayerCount-2 && botLayerNdx == copperLayerCount-1 ) )
306 {
307 via->SetViaType( VIATYPE::MICROVIA );
308 }
309 else
310 {
311 via->SetViaType( VIATYPE::BLIND_BURIED );
312 }
313
314 via->SetWidth( viaDiam );
315 via->SetLayerPair( m_pcbLayer2kicad[ topLayerNdx ], m_pcbLayer2kicad[ botLayerNdx ] );
316 }
317
318 wxASSERT( via );
319
320 via->SetNetCode( aNetCode );
321
322 // a via can be locked.
323 // However specctra as 4 types, none is exactly the same as our locked option
324 // aVia->via_type = T_fix, T_route, T_normal or T_protect
325 // fix and protect could be used as lock option
326 // but protect is returned for all tracks having initially the route or protect property
327 if( aVia->via_type == T_fix )
328 via->SetLocked( true );
329
330 return via;
331}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
std::string layer_id
Definition: specctra.h:775
double diameter
Definition: specctra.h:777
int Length() const
Return the number of ELEMs in this holder.
Definition: specctra.h:317
ELEM * shape
Definition: specctra.h:893
@ BLIND_BURIED
#define UNDEFINED_DRILL_DIAMETER
Definition: pcb_track.h:70
const double IU_PER_MM
Definition: base_units.h:77

References _, B_Cu, BLIND_BURIED, DSN::CIRCLE::diameter, F_Cu, findLayerName(), Format(), FROM_UTF8(), BOARD::GetCopperLayerCount(), EDA_IU_SCALE::IU_PER_MM, DSN::CIRCLE::layer_id, DSN::ELEM_HOLDER::Length(), m_pcbLayer2kicad, m_routeResolution, m_sessionBoard, DSN::mapPt(), MICROVIA, DSN::PADSTACK::padstack_id, pcbIUScale, DSN::scale(), DSN::WINDOW::shape, THROUGH, THROW_IO_ERROR, DSN::ELEM::Type(), UNDEFINED_DRILL_DIAMETER, via, and DSN::WIRE_VIA::via_type.

Referenced by FromSESSION().

◆ readCOMPnPIN()

void DSN::SPECCTRA_DB::readCOMPnPIN ( std::string *  component_id,
std::string *  pid_id 
)
private

Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen.

This function is specialized because pin_reference may or may not be using double quotes. Both of these are legal: U2-14 or "U2"-"14". The lexer treats the first one as a single T_SYMBOL, so in that case we have to split it into two here.

The caller should have already read in the first token comprising the pin_reference and it will be tested through CurTok().

Parameters
component_idWhere to put the text preceding the '-' hyphen.
pid_idWhere to put the text which trails the '-'.
Exceptions
IO_ERROR,ifthe next token or two do no make up a pin_reference, or there is an error reading from the input stream.

Definition at line 137 of file specctra.cpp.

138{
139 T tok;
140
141 static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
142
143 if( !IsSymbol( (T) CurTok() ) )
144 Expecting( pin_def );
145
146 // case for: A12-14, i.e. no wrapping quotes. This should be a single
147 // token, so split it.
148 if( CurTok() != T_STRING )
149 {
150 const char* toktext = CurText();
151 const char* dash = strchr( toktext, '-' );
152
153 if( !dash )
154 Expecting( pin_def );
155
156 while( toktext != dash )
157 *component_id += *toktext++;
158
159 ++toktext; // skip the dash
160
161 while( *toktext )
162 *pin_id += *toktext++;
163 }
164 else // quoted string: "U12"-"14" or "U12"-14, 3 tokens in either case
165 {
166 *component_id = CurText();
167
168 tok = NextTok();
169
170 if( tok!=T_DASH )
171 Expecting( pin_def );
172
173 NextTok(); // accept anything after the dash.
174 *pin_id = CurText();
175 }
176}

Referenced by doNET(), doSUPPLY_PIN(), and doWAS_IS().

◆ readTIME()

void DSN::SPECCTRA_DB::readTIME ( time_t *  time_stamp)
private

Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year".

This function is specialized because time_stamps occur more than once in a session file. The caller should not have already read in the first token comprising the time stamp.

Parameters
time_stampWhere to put the parsed time value.
Exceptions
IO_ERROR,ifthe next token or 8 do no make up a time stamp, or there is an error reading from the input stream.

Definition at line 179 of file specctra.cpp.

180{
181 T tok;
182
183 struct tm mytime;
184
185 static const char time_toks[] = "<month> <day> <hour> : <minute> : <second> <year>";
186
187 static const char* months[] = { // index 0 = Jan
188 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
189 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", nullptr
190 };
191
192 NeedSYMBOL(); // month
193
194 const char* ptok = CurText();
195
196 mytime.tm_mon = 0; // remains if we don't find a month match.
197
198 for( int m = 0; months[m]; ++m )
199 {
200 if( !strcasecmp( months[m], ptok ) )
201 {
202 mytime.tm_mon = m;
203 break;
204 }
205 }
206
207 tok = NextTok(); // day
208
209 if( tok != T_NUMBER )
210 Expecting( time_toks );
211
212 mytime.tm_mday = atoi( CurText() );
213
214 tok = NextTok(); // hour
215
216 if( tok != T_NUMBER )
217 Expecting( time_toks );
218
219 mytime.tm_hour = atoi( CurText() );
220
221 // : colon
222 NeedSYMBOL();
223
224 if( *CurText() != ':' || strlen( CurText() )!=1 )
225 Expecting( time_toks );
226
227 tok = NextTok(); // minute
228
229 if( tok != T_NUMBER )
230 Expecting( time_toks );
231
232 mytime.tm_min = atoi( CurText() );
233
234 // : colon
235 NeedSYMBOL();
236
237 if( *CurText() != ':' || strlen( CurText() )!=1 )
238 Expecting( time_toks );
239
240 tok = NextTok(); // second
241
242 if( tok != T_NUMBER )
243 Expecting( time_toks );
244
245 mytime.tm_sec = atoi( CurText() );
246
247 tok = NextTok(); // year
248
249 if( tok != T_NUMBER )
250 Expecting( time_toks );
251
252 mytime.tm_year = atoi( CurText() ) - 1900;
253
254 *time_stamp = mktime( &mytime );
255}

Referenced by doANCESTOR(), and doHISTORY().

◆ RevertFOOTPRINTs()

void DSN::SPECCTRA_DB::RevertFOOTPRINTs ( BOARD aBoard)

Flip the footprints which were on the back side of the board back to the back.

Definition at line 1810 of file specctra_export.cpp.

1811{
1813 return;
1814
1815 // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the
1816 // top view. Restore those that were flipped.
1817 // Note: to export footprints, the footprints were flipped around the X axis,
1818 for( FOOTPRINT* footprint : aBoard->Footprints() )
1819 {
1820 if( footprint->GetFlag() )
1821 {
1822 footprint->Flip( footprint->GetPosition(), false );
1823 footprint->SetFlag( 0 );
1824 }
1825 }
1826
1827 m_footprintsAreFlipped = false;
1828}

References BOARD::Footprints(), and m_footprintsAreFlipped.

Referenced by ExportBoardToSpecctraFile().

◆ SetPCB()

void DSN::SPECCTRA_DB::SetPCB ( PCB aPcb)
inline

Delete any existing PCB and replaces it with the given one.

Definition at line 3688 of file specctra.h.

3689 {
3690 delete m_pcb;
3691 m_pcb = aPcb;
3692 }

References m_pcb.

Referenced by ExportBoardToSpecctraFile(), and LoadPCB().

◆ SetSESSION()

void DSN::SPECCTRA_DB::SetSESSION ( SESSION aSession)
inline

Delete any existing SESSION and replaces it with the given one.

Definition at line 3699 of file specctra.h.

3700 {
3701 delete m_session;
3702 m_session = aSession;
3703 }

References m_session.

Referenced by LoadSESSION().

Member Data Documentation

◆ keywords

const KEYWORD DSN::SPECCTRA_DB::keywords[]
staticprivate

specctra DSN keywords

Definition at line 3977 of file specctra.h.

◆ m_bot_via_layer

int DSN::SPECCTRA_DB::m_bot_via_layer
private

Definition at line 4009 of file specctra.h.

Referenced by exportNETCLASS(), FromBOARD(), and SPECCTRA_DB().

◆ m_brd_outlines

SHAPE_POLY_SET DSN::SPECCTRA_DB::m_brd_outlines
private

Definition at line 3980 of file specctra.h.

Referenced by BuiltBoardOutlines(), and fillBOUNDARY().

◆ m_filename

wxString DSN::SPECCTRA_DB::m_filename
private

Definition at line 3982 of file specctra.h.

◆ m_footprintsAreFlipped

bool DSN::SPECCTRA_DB::m_footprintsAreFlipped
private

Definition at line 3985 of file specctra.h.

Referenced by FlipFOOTPRINTs(), RevertFOOTPRINTs(), and SPECCTRA_DB().

◆ m_kicadLayer2pcb

std::vector<int> DSN::SPECCTRA_DB::m_kicadLayer2pcb
private

maps BOARD layer number to PCB layer numbers

Definition at line 3991 of file specctra.h.

Referenced by buildLayerMaps(), FromBOARD(), and makeIMAGE().

◆ m_layerIds

STRINGS DSN::SPECCTRA_DB::m_layerIds
private

indexed by PCB layer number

Definition at line 3989 of file specctra.h.

Referenced by buildLayerMaps(), findLayerName(), FromBOARD(), makeIMAGE(), makePADSTACK(), and makeVia().

◆ m_nets

std::vector<NET*> DSN::SPECCTRA_DB::m_nets
private

we don't want ownership here permanently, so we don't use boost::ptr_vector

Definition at line 4005 of file specctra.h.

Referenced by deleteNETs(), and FromBOARD().

◆ m_padstackset

PADSTACKSET DSN::SPECCTRA_DB::m_padstackset
private

Definition at line 4002 of file specctra.h.

Referenced by FromBOARD(), and makeIMAGE().

◆ m_pcb

PCB* DSN::SPECCTRA_DB::m_pcb
private

◆ m_pcbLayer2kicad

std::vector<PCB_LAYER_ID> DSN::SPECCTRA_DB::m_pcbLayer2kicad
private

maps PCB layer number to BOARD layer numbers

Definition at line 3992 of file specctra.h.

Referenced by buildLayerMaps(), FromBOARD(), makePADSTACK(), makeTRACK(), and makeVIA().

◆ m_quote_char

std::string DSN::SPECCTRA_DB::m_quote_char
private

Definition at line 3983 of file specctra.h.

Referenced by doCLASS(), doPARSER(), doRULE(), ExportPCB(), ExportSESSION(), and SPECCTRA_DB().

◆ m_routeResolution

UNIT_RES* DSN::SPECCTRA_DB::m_routeResolution
private

used during FromSESSION() only, memory for it is not owned here.

Definition at line 3995 of file specctra.h.

Referenced by FromSESSION(), makeTRACK(), makeVIA(), and SPECCTRA_DB().

◆ m_session

SESSION* DSN::SPECCTRA_DB::m_session
private

◆ m_sessionBoard

BOARD* DSN::SPECCTRA_DB::m_sessionBoard
private

a copy to avoid passing as an argument, memory for it is not owned here.

Definition at line 3998 of file specctra.h.

Referenced by FromSESSION(), makeTRACK(), makeVIA(), and SPECCTRA_DB().

◆ m_sf

STRING_FORMATTER DSN::SPECCTRA_DB::m_sf
private

Definition at line 3987 of file specctra.h.

◆ m_top_via_layer

int DSN::SPECCTRA_DB::m_top_via_layer
private

specctra cu layers, 0 based index:

Definition at line 4008 of file specctra.h.

Referenced by exportNETCLASS(), FromBOARD(), and SPECCTRA_DB().

◆ scanPADs

const KICAD_T DSN::SPECCTRA_DB::scanPADs[]
staticprivate

Definition at line 4000 of file specctra.h.


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