more amazing free specctra work
This commit is contained in:
parent
10ded82dbd
commit
709be49518
|
@ -5,20 +5,29 @@ Started 2007-June-11
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2008-Feb-13 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
+pcbnew
|
||||
specctra export: now generate unique pin names from module padnames in the
|
||||
case where there are non-unique pad names within a module. Tested with
|
||||
Electra demo, and *.dsn files load OK in there as well as in freerouter.
|
||||
Stopped using reserved layer name "signal" and instead output a full
|
||||
padstack consisting of all pertinent layers for via, pads, and keepouts.
|
||||
|
||||
|
||||
2008-Feb-12 UPDATE Tim Hanson sideskate@gmail.com
|
||||
================================================================================
|
||||
+eeschema
|
||||
* commiting my changes to allow multiple instances of a given schematic file within a hierarchy:
|
||||
** internally, m_currentScreen has been replaced with m_currentSheet,
|
||||
which is a list or 'path' of screens. The path of screens is used to generate
|
||||
a series of timestamps, which is converted to flat component reference via a look-up
|
||||
table in the schematic files.
|
||||
** this means that m_currentScreen is no longer used -- use GetScreen().
|
||||
** GetScreen is virtual, as some of the dialogs keep around a WinEDA_BaseScreen pointer.
|
||||
** all sub-sheets in a given schematic must have different names to generate a meaningful netlist.
|
||||
* commiting my changes to allow multiple instances of a given schematic file within a hierarchy:
|
||||
** internally, m_currentScreen has been replaced with m_currentSheet,
|
||||
which is a list or 'path' of screens. The path of screens is used to generate
|
||||
a series of timestamps, which is converted to flat component reference via a look-up
|
||||
table in the schematic files.
|
||||
** this means that m_currentScreen is no longer used -- use GetScreen().
|
||||
** GetScreen is virtual, as some of the dialogs keep around a WinEDA_BaseScreen pointer.
|
||||
** all sub-sheets in a given schematic must have different names to generate a meaningful netlist.
|
||||
|
||||
|
||||
=======
|
||||
2008-Feb-12 UPDATE Igor Plyatov <plyatov@mail.ru>
|
||||
================================================================================
|
||||
+eeschema
|
||||
|
@ -26,6 +35,7 @@ email address.
|
|||
+all
|
||||
Russian translation update.
|
||||
|
||||
|
||||
2008-Feb-11 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
+pcbnew
|
||||
|
|
|
@ -27,7 +27,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
wxString text, msg;
|
||||
const BOARD_ITEM* item = this;
|
||||
EQUIPOT* net;
|
||||
D_PAD * pad;
|
||||
D_PAD * pad;
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
|
@ -42,17 +42,17 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
break;
|
||||
|
||||
case TYPEPAD:
|
||||
pad = (D_PAD *) this;
|
||||
pad = (D_PAD *) this;
|
||||
text << _( "Pad" ) << wxT( " \"" ) << pad->ReturnStringPadName()
|
||||
<< wxT( "\" (" );
|
||||
if ( (pad->m_Masque_Layer & ALL_CU_LAYERS) == ALL_CU_LAYERS )
|
||||
text << _("all copper layers");
|
||||
else if( (pad->m_Masque_Layer & CUIVRE_LAYER) == CUIVRE_LAYER )
|
||||
text << _("copper layer");
|
||||
else if( (pad->m_Masque_Layer & CMP_LAYER) == CMP_LAYER )
|
||||
text << _("cmp layer");
|
||||
else text << _("???");
|
||||
text << _( ") of " ) << ( (MODULE*) GetParent() )->GetReference();
|
||||
<< wxT( "\" (" );
|
||||
if ( (pad->m_Masque_Layer & ALL_CU_LAYERS) == ALL_CU_LAYERS )
|
||||
text << _("all copper layers");
|
||||
else if( (pad->m_Masque_Layer & CUIVRE_LAYER) == CUIVRE_LAYER )
|
||||
text << _("copper layer");
|
||||
else if( (pad->m_Masque_Layer & CMP_LAYER) == CMP_LAYER )
|
||||
text << _("cmp layer");
|
||||
else text << _("???");
|
||||
text << _( ") of " ) << ( (MODULE*) GetParent() )->GetReference();
|
||||
break;
|
||||
|
||||
case TYPEDRAWSEGMENT:
|
||||
|
@ -89,7 +89,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
break;
|
||||
|
||||
case TYPEEDGEMODULE:
|
||||
{
|
||||
{
|
||||
text << _( "Graphic" ) << wxT( " " );
|
||||
wxString cp;
|
||||
|
||||
|
@ -129,10 +129,10 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
|
||||
text << cp;
|
||||
text << wxT( " (" ) << ReturnPcbLayerName( ((EDGE_MODULE*) item )->m_Layer ).Trim() << wxT( ")" );
|
||||
text << _( " of " )
|
||||
text << _( " of " )
|
||||
<< ( (MODULE*) GetParent() )->GetReference();
|
||||
break;
|
||||
}
|
||||
}
|
||||
case TYPETRACK:
|
||||
// deleting tracks requires all the information we can get to
|
||||
// disambiguate all the crap under the cursor!
|
||||
|
@ -153,36 +153,36 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
|
||||
case TYPEZONE_CONTAINER:
|
||||
text = _( "Zone Outline" );
|
||||
{
|
||||
ZONE_CONTAINER* area = (ZONE_CONTAINER*) this;
|
||||
int ncont = area->m_Poly->GetContour(area->m_CornerSelection);
|
||||
if ( ncont ) text << wxT(" ") << _("(Cutout)");
|
||||
}
|
||||
text << wxT( " " );
|
||||
{
|
||||
ZONE_CONTAINER* area = (ZONE_CONTAINER*) this;
|
||||
int ncont = area->m_Poly->GetContour(area->m_CornerSelection);
|
||||
if ( ncont ) text << wxT(" ") << _("(Cutout)");
|
||||
}
|
||||
text << wxT( " " );
|
||||
{
|
||||
wxString TimeStampText;
|
||||
TimeStampText.Printf( wxT( "(%8.8X)" ), item->m_TimeStamp );
|
||||
text << TimeStampText;
|
||||
}
|
||||
if ( ((ZONE_CONTAINER*) item)->GetNet() >= 0 )
|
||||
{
|
||||
net = aPcb->FindNet( ( (ZONE_CONTAINER*) item )->GetNet() );
|
||||
if( net )
|
||||
{
|
||||
text << wxT( " [" ) << net->m_Netname << wxT( "]" );
|
||||
}
|
||||
}
|
||||
else // A netcode < 0 is an error flag (Netname not found or area not initialised)
|
||||
{
|
||||
text << wxT( " [" ) << ( (ZONE_CONTAINER*) item )->m_Netname << wxT( "]" );
|
||||
text << wxT(" <") << _("Not Found") << wxT(">");
|
||||
}
|
||||
if ( ((ZONE_CONTAINER*) item)->GetNet() >= 0 )
|
||||
{
|
||||
net = aPcb->FindNet( ( (ZONE_CONTAINER*) item )->GetNet() );
|
||||
if( net )
|
||||
{
|
||||
text << wxT( " [" ) << net->m_Netname << wxT( "]" );
|
||||
}
|
||||
}
|
||||
else // A netcode < 0 is an error flag (Netname not found or area not initialised)
|
||||
{
|
||||
text << wxT( " [" ) << ( (ZONE_CONTAINER*) item )->m_Netname << wxT( "]" );
|
||||
text << wxT(" <") << _("Not Found") << wxT(">");
|
||||
}
|
||||
text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
|
||||
break;
|
||||
break;
|
||||
|
||||
case TYPEZONE:
|
||||
text = _( "Zone" );
|
||||
text << wxT( " " );
|
||||
case TYPEZONE:
|
||||
text = _( "Zone" );
|
||||
text << wxT( " " );
|
||||
{
|
||||
wxString TimeStampText;
|
||||
TimeStampText.Printf( wxT( "(%8.8X)" ), item->m_TimeStamp );
|
||||
|
@ -213,6 +213,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
{
|
||||
text << wxT( " [" ) << net->m_Netname << wxT( "]" );
|
||||
}
|
||||
text << wxChar(' ') << _("Net:") << via->GetNet();
|
||||
|
||||
if( shape != VIA_THROUGH )
|
||||
{
|
||||
|
@ -236,7 +237,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
|
|||
break;
|
||||
|
||||
case TYPEMIRE:
|
||||
valeur_param( ((MIREPCB*)item)->m_Size, msg );
|
||||
valeur_param( ((MIREPCB*)item)->m_Size, msg );
|
||||
text << _( "Target" ) << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim()
|
||||
<< wxT( " " ) << _( "size" ) << wxT( " " ) << msg
|
||||
;
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace DSN {
|
|||
|
||||
//-----<SPECCTRA_DB>-------------------------------------------------
|
||||
|
||||
#if !defined(STANDALONE)
|
||||
|
||||
void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
|
||||
{
|
||||
|
@ -100,6 +101,7 @@ void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
|
|||
layerIds.push_back( CONV_TO_UTF8( aBoard->GetLayerName( kilayer ) ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const
|
||||
|
@ -183,13 +185,21 @@ void SPECCTRA_DB::needRIGHT() throw( IOError )
|
|||
expecting( T_RIGHT );
|
||||
}
|
||||
|
||||
void SPECCTRA_DB::needSYMBOL() throw( IOError )
|
||||
DSN_T SPECCTRA_DB::needSYMBOL() throw( IOError )
|
||||
{
|
||||
DSN_T tok = nextTok();
|
||||
if( !isSymbol( tok ) )
|
||||
expecting( T_SYMBOL );
|
||||
return tok;
|
||||
}
|
||||
|
||||
DSN_T SPECCTRA_DB::needSYMBOLorNUMBER() throw( IOError )
|
||||
{
|
||||
DSN_T tok = nextTok();
|
||||
if( !isSymbol( tok ) && tok!=T_NUMBER )
|
||||
expecting( "symbol|number" );
|
||||
return tok;
|
||||
}
|
||||
|
||||
void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IOError )
|
||||
{
|
||||
|
@ -467,7 +477,9 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
|
|||
|
||||
void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
|
||||
{
|
||||
DSN_T tok;
|
||||
DSN_T tok;
|
||||
std::string const1;
|
||||
std::string const2;
|
||||
|
||||
/* <parser_descriptor >::=
|
||||
(parser
|
||||
|
@ -519,17 +531,19 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
|
|||
break;
|
||||
|
||||
case T_host_version:
|
||||
needSYMBOL();
|
||||
needSYMBOLorNUMBER();
|
||||
growth->host_version = lexer->CurText();
|
||||
needRIGHT();
|
||||
break;
|
||||
|
||||
case T_constant:
|
||||
needSYMBOL();
|
||||
growth->const_id1 = lexer->CurText();
|
||||
needSYMBOL();
|
||||
growth->const_id2 = lexer->CurText();
|
||||
needSYMBOLorNUMBER();
|
||||
const1 = lexer->CurText();
|
||||
needSYMBOLorNUMBER();
|
||||
const2 = lexer->CurText();
|
||||
needRIGHT();
|
||||
growth->constants.push_back( const1 );
|
||||
growth->constants.push_back( const2 );
|
||||
break;
|
||||
|
||||
case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
|
||||
|
@ -710,6 +724,8 @@ void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth ) throw(IOError)
|
|||
break;
|
||||
|
||||
case T_layer_noise_weight:
|
||||
if( growth->layer_noise_weight )
|
||||
unexpected( tok );
|
||||
growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
|
||||
doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
|
||||
break;
|
||||
|
@ -755,11 +771,15 @@ L_place:
|
|||
break;
|
||||
|
||||
case T_via:
|
||||
if( growth->via )
|
||||
unexpected( tok );
|
||||
growth->via = new VIA( growth );
|
||||
doVIA( growth->via );
|
||||
break;
|
||||
|
||||
case T_control:
|
||||
if( growth->control )
|
||||
unexpected( tok );
|
||||
growth->control = new CONTROL( growth );
|
||||
doCONTROL( growth->control );
|
||||
break;
|
||||
|
@ -772,11 +792,15 @@ L_place:
|
|||
break;
|
||||
|
||||
case T_rule:
|
||||
if( growth->rules )
|
||||
unexpected( tok );
|
||||
growth->rules = new RULE( growth, T_rule );
|
||||
doRULE( growth->rules );
|
||||
break;
|
||||
|
||||
case T_place_rule:
|
||||
if( growth->place_rules )
|
||||
unexpected( tok );
|
||||
growth->place_rules = new RULE( growth, T_place_rule );
|
||||
doRULE( growth->place_rules );
|
||||
break;
|
||||
|
@ -2219,35 +2243,35 @@ void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
|
|||
|
||||
growth->padstack_id = lexer->CurText();
|
||||
|
||||
tok = nextTok();
|
||||
if( tok == T_LEFT )
|
||||
while( (tok = nextTok()) != T_RIGHT )
|
||||
{
|
||||
tok = nextTok();
|
||||
if( tok != T_rotate )
|
||||
expecting( T_rotate );
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = nextTok();
|
||||
if( tok != T_rotate )
|
||||
expecting( T_rotate );
|
||||
|
||||
if( nextTok() != T_NUMBER )
|
||||
expecting( T_NUMBER );
|
||||
growth->SetRotation( strtod( lexer->CurText(), 0 ) );
|
||||
needRIGHT();
|
||||
tok = nextTok();
|
||||
if( nextTok() != T_NUMBER )
|
||||
expecting( T_NUMBER );
|
||||
growth->SetRotation( strtod( lexer->CurText(), 0 ) );
|
||||
needRIGHT();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !isSymbol(tok) && tok!=T_NUMBER )
|
||||
expecting( "pin_id" );
|
||||
|
||||
growth->pin_id = lexer->CurText();
|
||||
|
||||
if( nextTok() != T_NUMBER )
|
||||
expecting( T_NUMBER );
|
||||
growth->vertex.x = strtod( lexer->CurText(), 0 );
|
||||
|
||||
if( nextTok() != T_NUMBER )
|
||||
expecting( T_NUMBER );
|
||||
growth->vertex.y = strtod( lexer->CurText(), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( !isSymbol(tok) && tok!=T_NUMBER )
|
||||
expecting( "pin_id" );
|
||||
|
||||
growth->pin_id = lexer->CurText();
|
||||
|
||||
if( nextTok() != T_NUMBER )
|
||||
expecting( T_NUMBER );
|
||||
growth->vertex.x = strtod( lexer->CurText(), 0 );
|
||||
|
||||
if( nextTok() != T_NUMBER )
|
||||
expecting( T_NUMBER );
|
||||
growth->vertex.y = strtod( lexer->CurText(), 0 );
|
||||
|
||||
if( nextTok() != T_RIGHT )
|
||||
unexpected( lexer->CurText() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2286,8 +2310,8 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
|
|||
|
||||
case T_padstack:
|
||||
PADSTACK* padstack;
|
||||
padstack = new PADSTACK( growth );
|
||||
growth->padstacks.push_back( padstack );
|
||||
padstack = new PADSTACK();
|
||||
growth->AddPadstack( padstack );
|
||||
doPADSTACK( padstack );
|
||||
break;
|
||||
|
||||
|
@ -2307,7 +2331,8 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
|
|||
|
||||
void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
|
||||
{
|
||||
DSN_T tok = nextTok();
|
||||
DSN_T tok = nextTok();
|
||||
PIN_REFS* pin_refs;
|
||||
|
||||
/* <net_descriptor >::=
|
||||
(net <net_id >
|
||||
|
@ -2358,14 +2383,38 @@ void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
|
|||
case T_pins:
|
||||
case T_order:
|
||||
growth->pins_type = tok;
|
||||
pin_refs = &growth->pins;
|
||||
goto L_pins;
|
||||
|
||||
case T_expose:
|
||||
pin_refs = &growth->expose;
|
||||
goto L_pins;
|
||||
|
||||
case T_noexpose:
|
||||
pin_refs = &growth->noexpose;
|
||||
goto L_pins;
|
||||
|
||||
case T_source:
|
||||
pin_refs = &growth->source;
|
||||
goto L_pins;
|
||||
|
||||
case T_load:
|
||||
pin_refs = &growth->load;
|
||||
goto L_pins;
|
||||
|
||||
case T_terminator:
|
||||
pin_refs = &growth->terminator;
|
||||
//goto L_pins;
|
||||
|
||||
L_pins:
|
||||
{
|
||||
PIN_REF empty( growth );
|
||||
while( (tok = nextTok()) != T_RIGHT )
|
||||
{
|
||||
// copy the empty one, then fill its copy later thru pin_ref.
|
||||
growth->pins.push_back( empty );
|
||||
pin_refs->push_back( empty );
|
||||
|
||||
PIN_REF* pin_ref = &growth->pins.back();
|
||||
PIN_REF* pin_ref = &pin_refs->back();
|
||||
|
||||
readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
|
||||
}
|
||||
|
@ -3431,7 +3480,7 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote
|
|||
if( strlen(wrapee)==0 )
|
||||
return quote_char;
|
||||
|
||||
bool isNumber = true;
|
||||
// bool isNumber = true;
|
||||
|
||||
for( ; *wrapee; ++wrapee )
|
||||
{
|
||||
|
@ -3444,12 +3493,12 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote
|
|||
if( strchr( quoteThese, *wrapee ) )
|
||||
return quote_char;
|
||||
|
||||
if( !strchr( "01234567890.-+", *wrapee ) )
|
||||
isNumber = false;
|
||||
// if( !strchr( "01234567890.-+", *wrapee ) )
|
||||
// isNumber = false;
|
||||
}
|
||||
|
||||
if( isNumber )
|
||||
return quote_char;
|
||||
// if( isNumber )
|
||||
// return quote_char;
|
||||
|
||||
return ""; // can use an unwrapped string.
|
||||
}
|
||||
|
@ -3670,6 +3719,11 @@ int ELEM_HOLDER::FindElem( DSN_T aType, int instanceNum )
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// a reasonably small memory price to pay for improved performance
|
||||
STRINGFORMATTER ELEM::sf;
|
||||
|
||||
|
||||
//-----<UNIT_RES>---------------------------------------------------------
|
||||
|
||||
UNIT_RES UNIT_RES::Default( NULL, T_resolution );
|
||||
|
@ -3679,6 +3733,8 @@ UNIT_RES UNIT_RES::Default( NULL, T_resolution );
|
|||
|
||||
int PADSTACK::Compare( PADSTACK* lhs, PADSTACK* rhs )
|
||||
{
|
||||
// printf( "PADSTACK::Compare( %p, %p)\n", lhs, rhs );
|
||||
|
||||
if( !lhs->hash.size() )
|
||||
lhs->hash = lhs->makeHash();
|
||||
|
||||
|
@ -3725,7 +3781,6 @@ int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
|
|||
*/
|
||||
|
||||
//-----<PARSER>-----------------------------------------------------------
|
||||
|
||||
PARSER::PARSER( ELEM* aParent ) :
|
||||
ELEM( T_parser, aParent )
|
||||
{
|
||||
|
@ -3752,10 +3807,17 @@ void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOErro
|
|||
out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
|
||||
out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
|
||||
|
||||
if( const_id1.length()>0 || const_id2.length()>0 )
|
||||
out->Print( nestLevel, "(constant %c%s%c %c%s%c)\n",
|
||||
string_quote, const_id1.c_str(), string_quote,
|
||||
string_quote, const_id2.c_str(), string_quote );
|
||||
for( STRINGS::iterator i=constants.begin(); i!=constants.end(); )
|
||||
{
|
||||
const std::string& s1 = *i++;
|
||||
const std::string& s2 = *i++;
|
||||
|
||||
const char* q1 = out->GetQuoteChar( s1.c_str() );
|
||||
const char* q2 = out->GetQuoteChar( s2.c_str() );
|
||||
out->Print( nestLevel, "(constant %s%s%s %s%s%s)\n",
|
||||
q1, s1.c_str(), q1,
|
||||
q2, s2.c_str(), q2 );
|
||||
}
|
||||
|
||||
if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor )
|
||||
out->Print( nestLevel, "(routes_include%s%s%s)\n",
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
// see http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
// see http://www.boost.org/libs/ptr_container/doc/ptr_set.html
|
||||
#include <boost/ptr_container/ptr_set.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "dsn.h"
|
||||
|
||||
|
@ -303,14 +307,16 @@ protected:
|
|||
*/
|
||||
std::string makeHash()
|
||||
{
|
||||
STRINGFORMATTER sf;
|
||||
|
||||
sf.Clear();
|
||||
FormatContents( &sf, 0 );
|
||||
sf.StripUseless();
|
||||
|
||||
return sf.GetString();
|
||||
}
|
||||
|
||||
// avoid creating this for every compare, make static.
|
||||
static STRINGFORMATTER sf;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -466,8 +472,8 @@ class PARSER : public ELEM
|
|||
bool via_rotate_first;
|
||||
bool generated_by_freeroute;
|
||||
|
||||
std::string const_id1;
|
||||
std::string const_id2;
|
||||
/// This holds pairs of strings, one pair for each constant definition
|
||||
STRINGS constants;
|
||||
|
||||
std::string host_cad;
|
||||
std::string host_version;
|
||||
|
@ -1924,12 +1930,16 @@ class PIN : public ELEM
|
|||
std::string pin_id;
|
||||
POINT vertex;
|
||||
|
||||
int kiNetCode; ///< kicad netcode
|
||||
|
||||
|
||||
public:
|
||||
PIN( ELEM* aParent ) :
|
||||
ELEM( T_pin, aParent )
|
||||
{
|
||||
rotation = 0.0;
|
||||
isRotated = false;
|
||||
kiNetCode = 0;
|
||||
}
|
||||
|
||||
void SetRotation( double aRotation )
|
||||
|
@ -1960,6 +1970,8 @@ public:
|
|||
vertex.x, vertex.y );
|
||||
}
|
||||
};
|
||||
typedef boost::ptr_vector<PIN> PINS;
|
||||
|
||||
|
||||
class LIBRARY;
|
||||
class IMAGE : public ELEM_HOLDER
|
||||
|
@ -1978,7 +1990,6 @@ class IMAGE : public ELEM_HOLDER
|
|||
the kids list.
|
||||
*/
|
||||
|
||||
typedef boost::ptr_vector<PIN> PINS;
|
||||
PINS pins;
|
||||
|
||||
RULE* rules;
|
||||
|
@ -2085,7 +2096,7 @@ typedef boost::ptr_vector<IMAGE> IMAGES;
|
|||
* Class PADSTACK
|
||||
* holds either a via or a pad definition.
|
||||
*/
|
||||
class PADSTACK : public ELEM_HOLDER
|
||||
class PADSTACK : public ELEM_HOLDER, private boost::noncopyable
|
||||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
|
@ -2105,8 +2116,14 @@ class PADSTACK : public ELEM_HOLDER
|
|||
|
||||
public:
|
||||
|
||||
PADSTACK( ELEM* aParent ) :
|
||||
ELEM_HOLDER( T_padstack, aParent )
|
||||
/**
|
||||
* Constructor PADSTACK()
|
||||
* cannot take ELEM* aParent because PADSTACKSET confuses this with a
|
||||
* copy constructor and causes havoc. Instead set parent with
|
||||
* LIBRARY::AddPadstack()
|
||||
*/
|
||||
PADSTACK() :
|
||||
ELEM_HOLDER( T_padstack, NULL )
|
||||
{
|
||||
unit = 0;
|
||||
rotate = T_on;
|
||||
|
@ -2131,6 +2148,7 @@ public:
|
|||
*/
|
||||
static int Compare( PADSTACK* lhs, PADSTACK* rhs );
|
||||
|
||||
|
||||
void SetPadstackId( const char* aPadstackId )
|
||||
{
|
||||
padstack_id = aPadstackId;
|
||||
|
@ -2194,6 +2212,15 @@ public:
|
|||
};
|
||||
typedef boost::ptr_vector<PADSTACK> PADSTACKS;
|
||||
|
||||
/**
|
||||
* Function operator<()
|
||||
* is used by the PADSTACKSET boost::ptr_set below
|
||||
*/
|
||||
inline bool operator<( const PADSTACK& lhs, const PADSTACK& rhs )
|
||||
{
|
||||
return PADSTACK::Compare( (PADSTACK*) &lhs, (PADSTACK*) &rhs ) < 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class LIBRARY
|
||||
|
@ -2228,6 +2255,7 @@ public:
|
|||
|
||||
void AddPadstack( PADSTACK* aPadstack )
|
||||
{
|
||||
aPadstack->SetParent( this );
|
||||
padstacks.push_back( aPadstack );
|
||||
}
|
||||
|
||||
|
@ -2537,10 +2565,15 @@ class NET : public ELEM
|
|||
bool unassigned;
|
||||
int net_number;
|
||||
|
||||
DSN_T pins_type; ///< T_pins | T_order
|
||||
|
||||
DSN_T pins_type; ///< T_pins | T_order, type of field 'pins' below
|
||||
PIN_REFS pins;
|
||||
|
||||
PIN_REFS expose;
|
||||
PIN_REFS noexpose;
|
||||
PIN_REFS source;
|
||||
PIN_REFS load;
|
||||
PIN_REFS terminator;
|
||||
|
||||
DSN_T type; ///< T_fix | T_normal
|
||||
|
||||
DSN_T supply; ///< T_power | T_ground
|
||||
|
@ -3525,6 +3558,9 @@ public:
|
|||
};
|
||||
|
||||
|
||||
typedef boost::ptr_set<PADSTACK> PADSTACKSET;
|
||||
|
||||
|
||||
/**
|
||||
* Class SPECCTRA_DB
|
||||
* holds a DSN data tree, usually coming from a DSN file.
|
||||
|
@ -3561,6 +3597,12 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
|
||||
static const KICAD_T scanPADs[];
|
||||
|
||||
PADSTACKSET padstackset;
|
||||
|
||||
/// we don't want ownership here permanently, so we don't use boost::ptr_vector
|
||||
std::vector<NET*> nets;
|
||||
|
||||
|
||||
/**
|
||||
* Function buildLayerMaps
|
||||
* creates a few data translation structures for layer name and number
|
||||
|
@ -3612,9 +3654,20 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
* calls nextTok() and then verifies that the token read in
|
||||
* satisfies bool isSymbol().
|
||||
* If not, an IOError is thrown.
|
||||
* @return DSN_T - the actual token read in.
|
||||
* @throw IOError, if the next token does not satisfy isSymbol()
|
||||
*/
|
||||
void needSYMBOL() throw( IOError );
|
||||
DSN_T needSYMBOL() throw( IOError );
|
||||
|
||||
/**
|
||||
* Function needSYMBOLorNUMBER
|
||||
* calls nextTok() and then verifies that the token read in
|
||||
* satisfies bool isSymbol() or tok==T_NUMBER.
|
||||
* If not, an IOError is thrown.
|
||||
* @return DSN_T - the actual token read in.
|
||||
* @throw IOError, if the next token does not satisfy the above test
|
||||
*/
|
||||
DSN_T needSYMBOLorNUMBER() throw( IOError );
|
||||
|
||||
/**
|
||||
* Function readCOMPnPIN
|
||||
|
@ -3718,28 +3771,35 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
/**
|
||||
* Function makeIMAGE
|
||||
* allocates an IMAGE on the heap and creates all the PINs according
|
||||
* to the PADs in the MODULE.
|
||||
* to the D_PADs in the MODULE.
|
||||
* @param aBoard The owner of the MODULE.
|
||||
* @param aModule The MODULE from which to build the IMAGE.
|
||||
* @return IMAGE* - not tested for duplication yet.
|
||||
*/
|
||||
IMAGE* makeIMAGE( MODULE* aModule );
|
||||
IMAGE* makeIMAGE( BOARD* aBoard, MODULE* aModule );
|
||||
|
||||
|
||||
/**
|
||||
* Function makePADSTACKs
|
||||
* makes all the PADSTACKs, and marks each D_PAD with the index into the
|
||||
* LIBRARY::padstacks list that it matches.
|
||||
* Function makePADSTACK
|
||||
* creates a PADSTACK which matches the given pad. Only pads which do not
|
||||
* satisfy the function isKeepout() should be passed to this function.
|
||||
* @param aPad The D_PAD which needs to be made into a PADSTACK.
|
||||
* @return PADSTACK* - The created padstack, including its padstack_id.
|
||||
*/
|
||||
void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads );
|
||||
|
||||
PADSTACK* makePADSTACK( BOARD* aBoard, D_PAD* aPad );
|
||||
|
||||
/**
|
||||
* Function makeVia
|
||||
* makes a round through hole PADSTACK using the given Kicad diameter in deci-mils.
|
||||
* @param aCopperDiameter The diameter of the copper pad.
|
||||
* @param aDrillDiameter The drill diameter, used on re-import of the session file.
|
||||
* @param aTopLayer The DSN::PCB top most layer index.
|
||||
* @param aBotLayer The DSN::PCB bottom most layer index.
|
||||
* @return PADSTACK* - The padstack, which is on the heap only, user must save
|
||||
* or delete it.
|
||||
*/
|
||||
PADSTACK* makeVia( int aCopperDiameter, int aDrillDiameter );
|
||||
PADSTACK* makeVia( int aCopperDiameter, int aDrillDiameter,
|
||||
int aTopLayer, int aBotLayer );
|
||||
|
||||
/**
|
||||
* Function makeVia
|
||||
|
@ -3751,6 +3811,19 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
PADSTACK* makeVia( const SEGVIA* aVia );
|
||||
|
||||
|
||||
/**
|
||||
* Function deleteNETs
|
||||
* deletes all the NETs that may be in here.
|
||||
*/
|
||||
void deleteNETs()
|
||||
{
|
||||
for( unsigned n=0; n<nets.size(); ++n )
|
||||
delete nets[n];
|
||||
|
||||
nets.clear();
|
||||
}
|
||||
|
||||
|
||||
//-----<FromSESSION>-----------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -3786,6 +3859,8 @@ public:
|
|||
delete pcb;
|
||||
delete session;
|
||||
|
||||
deleteNETs();
|
||||
|
||||
if( fp )
|
||||
fclose( fp );
|
||||
}
|
||||
|
|
|
@ -40,7 +40,9 @@
|
|||
|
||||
#include "trigo.h" // RotatePoint()
|
||||
#include <set> // std::set
|
||||
#include <map> // std::map
|
||||
|
||||
#include <boost/utility.hpp> // boost::addressof()
|
||||
|
||||
using namespace DSN;
|
||||
|
||||
|
@ -286,15 +288,15 @@ static bool isKeepout( D_PAD* aPad )
|
|||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr )
|
||||
/**************************************************************************/
|
||||
{
|
||||
const D_PAD* padref = *(D_PAD**)refptr;
|
||||
const D_PAD* padcmp = *(D_PAD**)objptr;
|
||||
|
||||
return D_PAD::Compare( padref, padcmp );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
|
@ -312,11 +314,221 @@ static PATH* makePath( const POINT& aStart, const POINT& aEnd, const std::string
|
|||
}
|
||||
|
||||
|
||||
IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
|
||||
/**
|
||||
* Struct wxString_less_than_
|
||||
* is used the std:set<> and std::map<> instantiations below.
|
||||
* See STRINGSET typedef and PINMAP typedef below.
|
||||
*/
|
||||
struct wxString_less_than
|
||||
{
|
||||
PADSTACKS& padstacks = pcb->library->padstacks;
|
||||
// a "less than" test on two wxStrings, by pointer.
|
||||
bool operator()( const wxString& s1, const wxString& s2) const
|
||||
{
|
||||
return s1.Cmp( s2 ) < 0; // case specific wxString compare
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function makePADSTACK
|
||||
* creates a PADSTACK which matches the given pad. Only pads which do not
|
||||
* satisfy the function isKeepout() should be passed to this function.
|
||||
* @param aPad The D_PAD which needs to be made into a PADSTACK.
|
||||
* @return PADSTACK* - The created padstack, including its padstack_id.
|
||||
*/
|
||||
PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
|
||||
{
|
||||
char name[80]; // padstack name builder
|
||||
std::string uniqifier;
|
||||
|
||||
bool doLayer[2] = { // top and bottom layers only
|
||||
aPad->IsOnLayer( LAYER_CMP_N ),
|
||||
aPad->IsOnLayer( COPPER_LAYER_N )
|
||||
};
|
||||
|
||||
// caller must do this screen before calling here.
|
||||
wxASSERT( !isKeepout( aPad ) );
|
||||
|
||||
wxASSERT( doLayer[0] || doLayer[1] );
|
||||
|
||||
PADSTACK* padstack = new PADSTACK();
|
||||
|
||||
int reportedLayers = 0; // how many in reported padstack
|
||||
const char* layerName[NB_COPPER_LAYERS];
|
||||
|
||||
if( aPad->m_Attribut==PAD_SMD || aPad->m_Attribut==PAD_CONN )
|
||||
{
|
||||
// PAD_SMD and PAD_CONN are reported on each layer for which
|
||||
// they are present.
|
||||
uniqifier = '[';
|
||||
|
||||
if( doLayer[0] )
|
||||
{
|
||||
layerName[reportedLayers++] = layerIds[0].c_str();
|
||||
uniqifier += 'T'; // T for top, could have used a layer index here alternatively
|
||||
}
|
||||
if( doLayer[1] )
|
||||
{
|
||||
int pcbLayerNdx = kicadLayer2pcb[COPPER_LAYER_N];
|
||||
layerName[reportedLayers++] = layerIds[ pcbLayerNdx ].c_str();
|
||||
uniqifier += 'B'; // B for bottom
|
||||
}
|
||||
|
||||
uniqifier += ']';
|
||||
}
|
||||
|
||||
else // through hole pad
|
||||
{
|
||||
#if 0
|
||||
/* Through hole pads are reported on the <reserved_layer_name>
|
||||
"signal". Reporting through hole pads on the special
|
||||
"signal" layer may have problems when power layers are in the layer
|
||||
stack. See bottom of page 74 of the SECCTRA Design Language
|
||||
Reference, May 2000. We could do better if there was actually a
|
||||
"layer type" field within Kicad which would hold one of: T_signal,
|
||||
T_power, T_mixed, T_jumper.
|
||||
*/
|
||||
|
||||
reportedLayers = 1;
|
||||
layerName[0] = signal;
|
||||
uniqifier = "[A]"; // A for all
|
||||
|
||||
#else
|
||||
// Through hole pads are reported on *all* copper layers.
|
||||
int copperLayers = aBoard->GetCopperLayerCount();
|
||||
|
||||
for( int layer=0; layer<copperLayers; ++layer )
|
||||
{
|
||||
layerName[reportedLayers++] = layerIds[layer].c_str();
|
||||
}
|
||||
uniqifier = "[A]"; // A for all
|
||||
#endif
|
||||
}
|
||||
|
||||
switch( aPad->m_PadShape )
|
||||
{
|
||||
default:
|
||||
case PAD_CIRCLE:
|
||||
{
|
||||
double diameter = scale(aPad->m_Size.x);
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
CIRCLE* circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
|
||||
circle->SetLayerId( layerName[ndx] );
|
||||
circle->SetDiameter( diameter );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Round%sPad_%.6g_mil",
|
||||
uniqifier.c_str(), scale(aPad->m_Size.x) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
padstack->SetPadstackId( name );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_RECT:
|
||||
{
|
||||
double dx = scale( aPad->m_Size.x ) / 2.0;
|
||||
double dy = scale( aPad->m_Size.y ) / 2.0;
|
||||
|
||||
POINT lowerLeft( -dx, -dy );
|
||||
POINT upperRight( dx, dy );
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
RECTANGLE* rect = new RECTANGLE( shape );
|
||||
shape->SetShape( rect );
|
||||
|
||||
rect->SetLayerId( layerName[ndx] );
|
||||
rect->SetCorners( lowerLeft, upperRight );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Rect%sPad_%.6gx%.6g_mil",
|
||||
uniqifier.c_str(), scale(aPad->m_Size.x), scale(aPad->m_Size.y) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
|
||||
padstack->SetPadstackId( name );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_OVAL:
|
||||
{
|
||||
double dx = scale( aPad->m_Size.x ) / 2.0;
|
||||
double dy = scale( aPad->m_Size.y ) / 2.0;
|
||||
double dr = dx - dy;
|
||||
|
||||
if( dr >= 0 ) // oval is horizontal
|
||||
{
|
||||
double radius = dy;
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape;
|
||||
PATH* path;
|
||||
// see http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
|
||||
shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
path = makePath( POINT(-dr, 0.0), POINT(dr, 0.0), layerName[ndx] );
|
||||
shape->SetShape( path );
|
||||
path->aperture_width = 2.0 * radius;
|
||||
}
|
||||
}
|
||||
else // oval is vertical
|
||||
{
|
||||
double radius = dx;
|
||||
|
||||
dr = -dr;
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape;
|
||||
PATH* path;
|
||||
// see http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
|
||||
shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
path = makePath( POINT(0.0, -dr), POINT(0.0, dr), layerName[ndx] );
|
||||
shape->SetShape( path );
|
||||
path->aperture_width = 2.0 * radius;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Oval%sPad_%.6gx%.6g_mil",
|
||||
uniqifier.c_str(), scale(aPad->m_Size.x), scale(aPad->m_Size.y) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
|
||||
padstack->SetPadstackId( name );
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case PAD_TRAPEZOID:
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
||||
return padstack;
|
||||
}
|
||||
|
||||
|
||||
/// data type used to ensure unique-ness of pin names
|
||||
typedef std::map<wxString, int, wxString_less_than> PINMAP;
|
||||
typedef std::pair<const wxString, int> PINMAP_PAIR;
|
||||
|
||||
|
||||
IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule )
|
||||
{
|
||||
PINMAP pinmap;
|
||||
TYPE_COLLECTOR pads;
|
||||
wxString padName;
|
||||
|
||||
|
||||
// get all the MODULE's pads.
|
||||
pads.Collect( aModule, scanPADs );
|
||||
|
@ -333,25 +545,64 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
|
|||
// see if this pad is a through hole with no copper on its perimeter
|
||||
if( isKeepout( pad ) )
|
||||
{
|
||||
KEEPOUT* keepout = new KEEPOUT(image, T_keepout);
|
||||
image->keepouts.push_back( keepout );
|
||||
double diameter = scale( pad->m_Drill.x );
|
||||
POINT vertex = mapPt( pad->m_Pos0 );
|
||||
|
||||
CIRCLE* circle = new CIRCLE(keepout);
|
||||
keepout->SetShape( circle );
|
||||
int layerCount = aBoard->GetCopperLayerCount();
|
||||
for( int layer=0; layer<layerCount; ++layer )
|
||||
{
|
||||
KEEPOUT* keepout = new KEEPOUT(image, T_keepout);
|
||||
image->keepouts.push_back( keepout );
|
||||
|
||||
circle->SetDiameter( scale(pad->m_Drill.x) );
|
||||
circle->SetVertex( mapPt( pad->m_Pos0 ) );
|
||||
circle->layer_id = "signal";
|
||||
CIRCLE* circle = new CIRCLE( keepout );
|
||||
keepout->SetShape( circle );
|
||||
|
||||
circle->SetDiameter( diameter );
|
||||
circle->SetVertex( vertex );
|
||||
circle->SetLayerId( layerIds[layer].c_str() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PADSTACK* padstack = &padstacks[pad->m_logical_connexion];
|
||||
PADSTACK* padstack = makePADSTACK( aBoard, pad );
|
||||
|
||||
PADSTACKSET::iterator iter = padstackset.find( *padstack );
|
||||
if( iter != padstackset.end() )
|
||||
{
|
||||
// padstack is a duplicate, delete it and use the original
|
||||
delete padstack;
|
||||
padstack = (PADSTACK*) *iter.base(); // folk lore, becareful here
|
||||
}
|
||||
else
|
||||
{
|
||||
padstackset.insert( padstack );
|
||||
}
|
||||
|
||||
PIN* pin = new PIN(image);
|
||||
|
||||
padName = pad->ReturnStringPadName();
|
||||
pin->pin_id = CONV_TO_UTF8( padName );
|
||||
|
||||
if( padName!=wxEmptyString && pinmap.find( padName )==pinmap.end() )
|
||||
{
|
||||
pinmap[ padName ] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
int duplicates = ++pinmap[ padName ];
|
||||
|
||||
sprintf( buf, "@%d", duplicates );
|
||||
|
||||
pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
|
||||
}
|
||||
|
||||
pin->kiNetCode = pad->GetNet();
|
||||
|
||||
image->pins.push_back( pin );
|
||||
|
||||
pin->padstack_id = padstack->padstack_id;
|
||||
pin->pin_id = CONV_TO_UTF8( pad->ReturnStringPadName() );
|
||||
|
||||
wxPoint pos( pad->m_Pos0 );
|
||||
wxPoint offset( pad->m_Offset.x, pad->m_Offset.y );
|
||||
|
@ -378,93 +629,31 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
|
|||
}
|
||||
|
||||
|
||||
PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
|
||||
{
|
||||
CIRCLE* circle;
|
||||
SHAPE* shape;
|
||||
double dsnDiameter;
|
||||
char name[48];
|
||||
|
||||
PADSTACK* padstack = new PADSTACK( pcb->library );
|
||||
|
||||
switch( aVia->Shape() )
|
||||
{
|
||||
case VIA_THROUGH:
|
||||
shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
|
||||
dsnDiameter = scale( aVia->m_Width );
|
||||
circle->SetDiameter( dsnDiameter );
|
||||
|
||||
circle->SetLayerId( "signal" );
|
||||
|
||||
snprintf( name, sizeof(name), "Via[A]%.6g:%.6g_mil", dsnDiameter,
|
||||
// encode the drill value into the name for later import
|
||||
scale( aVia->GetDrillValue() ) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
padstack->SetPadstackId( name );
|
||||
break;
|
||||
|
||||
case VIA_BLIND_BURIED:
|
||||
case VIA_MICROVIA:
|
||||
int topLayer;
|
||||
int botLayer;
|
||||
aVia->ReturnLayerPair( &topLayer, &botLayer );
|
||||
topLayer = kicadLayer2pcb[topLayer];
|
||||
botLayer = kicadLayer2pcb[botLayer];
|
||||
if( topLayer > botLayer )
|
||||
EXCHG( topLayer, botLayer );
|
||||
|
||||
dsnDiameter = scale( aVia->m_Width );
|
||||
|
||||
for( int layer=topLayer; layer<=botLayer; ++layer )
|
||||
{
|
||||
shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
|
||||
circle->SetDiameter( dsnDiameter );
|
||||
circle->SetLayerId( layerIds[layer].c_str() );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Via[%d-%d]_%.6g:%.6g_mil",
|
||||
topLayer, botLayer, dsnDiameter,
|
||||
// encode the drill value into the name for later import
|
||||
scale( aVia->GetDrillValue() )
|
||||
);
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
padstack->SetPadstackId( name );
|
||||
break;
|
||||
}
|
||||
|
||||
return padstack;
|
||||
}
|
||||
|
||||
|
||||
PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter )
|
||||
PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter,
|
||||
int aTopLayer, int aBotLayer )
|
||||
{
|
||||
char name[48];
|
||||
PADSTACK* padstack = new PADSTACK( pcb->library );
|
||||
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
CIRCLE* circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
PADSTACK* padstack = new PADSTACK();
|
||||
|
||||
double dsnDiameter = scale(aCopperDiameter);
|
||||
circle->SetDiameter( dsnDiameter );
|
||||
|
||||
circle->SetLayerId( "signal" );
|
||||
for( int layer=aTopLayer; layer<=aBotLayer; ++layer )
|
||||
{
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
snprintf( name, sizeof(name), "Via[A]%.6g:%.6g_mil", dsnDiameter,
|
||||
// encode the drill value into the name for later import
|
||||
scale( aDrillDiameter ) );
|
||||
CIRCLE* circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
|
||||
circle->SetDiameter( dsnDiameter );
|
||||
circle->SetLayerId( layerIds[layer].c_str() );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Via[%d-%d]_%.6g:%.6g_mil",
|
||||
aTopLayer, aBotLayer, dsnDiameter,
|
||||
// encode the drill value into the name for later import
|
||||
scale( aDrillDiameter )
|
||||
);
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
padstack->SetPadstackId( name );
|
||||
|
||||
|
@ -472,262 +661,32 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Struct ltWX
|
||||
* is used secretly by the std:set<> class below. See STRINGSET typedef.
|
||||
*/
|
||||
struct ltWX
|
||||
PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
|
||||
{
|
||||
// a "less than" test on two wxStrings, by pointer.
|
||||
bool operator()( const wxString* s1, const wxString* s2) const
|
||||
{
|
||||
return s1->Cmp( *s2 ) < 0; // case specific wxString compare
|
||||
}
|
||||
};
|
||||
int topLayer;
|
||||
int botLayer;
|
||||
|
||||
aVia->ReturnLayerPair( &topLayer, &botLayer );
|
||||
|
||||
topLayer = kicadLayer2pcb[topLayer];
|
||||
botLayer = kicadLayer2pcb[botLayer];
|
||||
|
||||
if( topLayer > botLayer )
|
||||
EXCHG( topLayer, botLayer );
|
||||
|
||||
return makeVia( aVia->m_Width, aVia->GetDrillValue(), topLayer, botLayer );
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
|
||||
{
|
||||
char name[80]; // padstack name builder
|
||||
std::string uniqifier;
|
||||
|
||||
if( aPads.GetCount() )
|
||||
{
|
||||
qsort( (void*) aPads.BasePtr(), aPads.GetCount(), sizeof(D_PAD*), Pad_list_Sort_by_Shapes );
|
||||
}
|
||||
|
||||
D_PAD* old_pad = NULL;
|
||||
|
||||
for( int i=0; i<aPads.GetCount(); ++i )
|
||||
{
|
||||
D_PAD* pad = (D_PAD*) aPads[i];
|
||||
|
||||
bool doLayer[2] = { // top and bottom layers only
|
||||
pad->IsOnLayer( LAYER_CMP_N ),
|
||||
pad->IsOnLayer( COPPER_LAYER_N )
|
||||
};
|
||||
|
||||
if( old_pad && 0==D_PAD::Compare( old_pad, pad ) )
|
||||
{
|
||||
// padstacks.size()-1 is the index of the matching padstack in LIBRARY::padstacks
|
||||
pad->m_logical_connexion = pcb->library->padstacks.size()-1;
|
||||
|
||||
// this is the same as the last pad, so do not add it to the padstack list.
|
||||
continue;
|
||||
}
|
||||
|
||||
// if pad has no copper presence, then it will be made into
|
||||
// an "image->keepout" later. No copper pad here, it is probably a hole.
|
||||
if( (!doLayer[0] && !doLayer[1]) || isKeepout( pad ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
old_pad = pad;
|
||||
|
||||
PADSTACK* padstack = new PADSTACK( pcb->library );
|
||||
pcb->library->AddPadstack( padstack );
|
||||
|
||||
// padstacks.size()-1 is the index of the matching padstack in LIBRARY::padstacks
|
||||
pad->m_logical_connexion = pcb->library->padstacks.size()-1;
|
||||
|
||||
/* Through hole pads are reported on the <reserved_layer_name>
|
||||
"signal". Reporting through hole pads on the special
|
||||
"signal" layer may have problems when power layers are in the layer
|
||||
stack. See bottom of page 74 of the SECCTRA Design Language
|
||||
Reference, May 2000. We could do better if there was actually a
|
||||
"layer type" field within Kicad which would hold one of: T_signal,
|
||||
T_power, T_mixed, T_jumper.
|
||||
|
||||
PAD_SMD and PAD_CONN are reported on each layer for which
|
||||
they are present.
|
||||
*/
|
||||
|
||||
int reportedLayers; // how many in reported padstack
|
||||
const char* layerName[NB_COPPER_LAYERS];
|
||||
|
||||
static const char signal[] = "signal";
|
||||
|
||||
if( pad->m_Attribut==PAD_SMD || pad->m_Attribut==PAD_CONN )
|
||||
{
|
||||
reportedLayers = 0;
|
||||
|
||||
uniqifier = '[';
|
||||
|
||||
if( doLayer[0] )
|
||||
{
|
||||
layerName[reportedLayers++] = layerIds[0].c_str();
|
||||
uniqifier += 'T'; // T for top, could have used a layer index here alternatively
|
||||
}
|
||||
if( doLayer[1] )
|
||||
{
|
||||
int pcbLayerNdx = kicadLayer2pcb[COPPER_LAYER_N];
|
||||
layerName[reportedLayers++] = layerIds[ pcbLayerNdx ].c_str();
|
||||
uniqifier += 'B'; // B for bottom
|
||||
}
|
||||
|
||||
uniqifier += ']';
|
||||
}
|
||||
else
|
||||
{
|
||||
reportedLayers = 1;
|
||||
layerName[0] = signal;
|
||||
uniqifier = "[A]"; // A for all
|
||||
}
|
||||
|
||||
switch( pad->m_PadShape )
|
||||
{
|
||||
default:
|
||||
case PAD_CIRCLE:
|
||||
{
|
||||
double diameter = scale(pad->m_Size.x);
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
CIRCLE* circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
|
||||
circle->SetLayerId( layerName[ndx] );
|
||||
circle->SetDiameter( diameter );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Round%sPad_%.6g_mil",
|
||||
uniqifier.c_str(), scale(pad->m_Size.x) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
|
||||
// @todo verify that all pad names are unique, there is a chance that
|
||||
// D_PAD::Compare() could say two pads are different, yet the get the same
|
||||
// name here. If so, blend in the padNdx into the name.
|
||||
|
||||
padstack->SetPadstackId( name );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_RECT:
|
||||
{
|
||||
double dx = scale( pad->m_Size.x ) / 2.0;
|
||||
double dy = scale( pad->m_Size.y ) / 2.0;
|
||||
|
||||
POINT lowerLeft( -dx, -dy );
|
||||
POINT upperRight( dx, dy );
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
||||
RECTANGLE* rect = new RECTANGLE( shape );
|
||||
shape->SetShape( rect );
|
||||
|
||||
rect->SetLayerId( layerName[ndx] );
|
||||
rect->SetCorners( lowerLeft, upperRight );
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Rect%sPad_%.6gx%.6g_mil",
|
||||
uniqifier.c_str(), scale(pad->m_Size.x), scale(pad->m_Size.y) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
|
||||
// @todo verify that all pad names are unique, there is a chance that
|
||||
// D_PAD::Compare() could say two pads are different, yet they get the same
|
||||
// name here. If so, blend in the padNdx into the name.
|
||||
|
||||
padstack->SetPadstackId( name );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_OVAL:
|
||||
{
|
||||
double dx = scale( pad->m_Size.x ) / 2.0;
|
||||
double dy = scale( pad->m_Size.y ) / 2.0;
|
||||
double dr = dx - dy;
|
||||
|
||||
if( dr >= 0 ) // oval is horizontal
|
||||
{
|
||||
double radius = dy;
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape;
|
||||
PATH* path;
|
||||
// see http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
|
||||
shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
path = makePath( POINT(-dr, 0.0), POINT(dr, 0.0), layerName[ndx] );
|
||||
shape->SetShape( path );
|
||||
path->aperture_width = 2.0 * radius;
|
||||
}
|
||||
}
|
||||
else // oval is vertical
|
||||
{
|
||||
double radius = dx;
|
||||
|
||||
dr = -dr;
|
||||
|
||||
for( int ndx=0; ndx<reportedLayers; ++ndx )
|
||||
{
|
||||
SHAPE* shape;
|
||||
PATH* path;
|
||||
// see http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
|
||||
shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
path = makePath( POINT(0.0, -dr), POINT(0.0, dr), layerName[ndx] );
|
||||
shape->SetShape( path );
|
||||
path->aperture_width = 2.0 * radius;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Oval%sPad_%.6gx%.6g_mil",
|
||||
uniqifier.c_str(), scale(pad->m_Size.x), scale(pad->m_Size.y) );
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
|
||||
// @todo verify that all pad names are unique, there is a chance that
|
||||
// D_PAD::Compare() could say two pads are different, yet they get the same
|
||||
// name here. If so, blend in the padNdx into the name.
|
||||
|
||||
padstack->SetPadstackId( name );
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case PAD_TRAPEZOID:
|
||||
break;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// unique pads are now in the padstack list.
|
||||
// next we add the via's which may be used.
|
||||
|
||||
int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize;
|
||||
if( defaultViaSize )
|
||||
{
|
||||
PADSTACK* padstack = makeVia( defaultViaSize, g_DesignSettings.m_ViaDrill );
|
||||
pcb->library->AddPadstack( padstack );
|
||||
|
||||
// remember this index, it is the default via and also the start of the
|
||||
// vias within the padstack list. Before this index are the pads.
|
||||
// At this index and later are the vias.
|
||||
pcb->library->SetViaStartIndex( pcb->library->padstacks.size()-1 );
|
||||
|
||||
// padstack->SetPadstackId( "Via_Default" ); I like the padstack_id with the size in it.
|
||||
}
|
||||
|
||||
for( int i=0; i<HISTORY_NUMBER; ++i )
|
||||
{
|
||||
int viaSize = aBoard->m_BoardSettings->m_ViaSizeHistory[i];
|
||||
if( !viaSize )
|
||||
break;
|
||||
|
||||
if( viaSize == defaultViaSize )
|
||||
continue;
|
||||
|
||||
PADSTACK* padstack = makeVia( viaSize, g_DesignSettings.m_ViaDrill );
|
||||
pcb->library->AddPadstack( padstack );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef std::set<wxString, wxString_less_than> STRINGSET;
|
||||
typedef std::pair<STRINGSET::iterator, bool> STRINGSET_PAIR;
|
||||
|
||||
|
||||
void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
||||
|
@ -740,14 +699,15 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
|||
|
||||
// Not all boards are exportable. Check that all reference Ids are unique.
|
||||
// Unless they are unique, we cannot import the session file which comes
|
||||
// back to us later from the router.
|
||||
// back to us later from the router. Also check that all pad names within
|
||||
// a part are unique, otherwise Electra and Freerouter will not draw the
|
||||
// pads properly.
|
||||
{
|
||||
TYPE_COLLECTOR padItems;
|
||||
|
||||
items.Collect( aBoard, scanMODULEs );
|
||||
|
||||
typedef std::set<const wxString*, ltWX> STRINGSET;
|
||||
typedef std::pair<STRINGSET::iterator, bool> PAIR;
|
||||
|
||||
STRINGSET references; // holds unique component references
|
||||
STRINGSET refs; // holds module reference designators
|
||||
|
||||
for( int i=0; i<items.GetCount(); ++i )
|
||||
{
|
||||
|
@ -760,8 +720,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
|||
}
|
||||
|
||||
// if we cannot insert OK, that means the reference has been seen before.
|
||||
PAIR pair = references.insert( &module->GetReference() );
|
||||
if( !pair.second ) // insert failed
|
||||
STRINGSET_PAIR refpair = refs.insert( module->GetReference() );
|
||||
if( !refpair.second ) // insert failed
|
||||
{
|
||||
ThrowIOError( _("Multiple components have identical reference IDs of \"%s\"."),
|
||||
module->GetReference().GetData() );
|
||||
|
@ -785,11 +745,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
|||
}
|
||||
}
|
||||
|
||||
// Since none of these statements cause any immediate output, the order
|
||||
// of them is somewhat flexible. The outputting to disk is done at the
|
||||
// end. We start by gathering all the layer information from the board.
|
||||
|
||||
|
||||
//-----<layer_descriptor>-----------------------------------------------
|
||||
{
|
||||
// specctra wants top physical layer first, then going down to the
|
||||
|
@ -818,10 +773,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// for now, report on only the top and bottom layers with respect to the copper
|
||||
// within a pad's padstack. this is usually correct, but not rigorous.
|
||||
|
||||
// a space in a quoted token is NOT a terminator, true establishes this.
|
||||
pcb->parser->space_in_quoted_tokens = true;
|
||||
|
||||
|
@ -1004,49 +955,78 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
|||
}
|
||||
|
||||
// keepouts could go here, there are none in Kicad at this time.
|
||||
// although COPPER_PLANEs probably will need them for the thru holes, etc.
|
||||
// but in that case they are WINDOWs within the COPPER_PLANEs.
|
||||
|
||||
|
||||
//-----<build the initial padstack list>--------------------------------
|
||||
//-----<build the images, components, and netlist>-----------------------
|
||||
{
|
||||
TYPE_COLLECTOR pads;
|
||||
// find the highest numbered netCode within the board.
|
||||
int highestNetCode = -1;
|
||||
for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() )
|
||||
highestNetCode = MAX( highestNetCode, equipot->GetNet() );
|
||||
|
||||
// get all the D_PADs into 'pads'.
|
||||
pads.Collect( aBoard, scanPADs );
|
||||
deleteNETs();
|
||||
|
||||
makePADSTACKs( aBoard, pads );
|
||||
// expand the net vector to highestNetCode+1, setting empty to NULL
|
||||
nets.resize( highestNetCode+1, NULL );
|
||||
|
||||
#if 0 && defined(DEBUG)
|
||||
for( int p=0; p<pads.GetCount(); ++p )
|
||||
pads[p]->Show( 0, std::cout );
|
||||
#endif
|
||||
}
|
||||
// skip netcode = 0
|
||||
for( unsigned i=1; i<nets.size(); ++i )
|
||||
nets[i] = new NET( pcb->network );
|
||||
|
||||
for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() )
|
||||
{
|
||||
int netcode = equipot->GetNet();
|
||||
if( netcode > 0 )
|
||||
nets[ netcode ]->net_id = CONV_TO_UTF8( equipot->m_Netname );
|
||||
}
|
||||
|
||||
//-----<build the images and components>---------------------------------
|
||||
{
|
||||
items.Collect( aBoard, scanMODULEs );
|
||||
|
||||
padstackset.clear();
|
||||
|
||||
for( int m=0; m<items.GetCount(); ++m )
|
||||
{
|
||||
MODULE* module = (MODULE*) items[m];
|
||||
|
||||
IMAGE* image = makeIMAGE( module );
|
||||
IMAGE* image = makeIMAGE( aBoard, module );
|
||||
|
||||
// create a net list entry for all the actual pins in the image
|
||||
// for the current module. location of this code is critical
|
||||
// because we fabricated some pin names to ensure unique-ness
|
||||
// of pin names within a module, do not move this code. The
|
||||
// exported netlist will have some fabricated pin names in it.
|
||||
// If you don't like fabricated pin names, then make sure all pads
|
||||
// within your MODULEs are uniquely named!
|
||||
|
||||
PIN_REF empty( pcb->network );
|
||||
for( unsigned p=0; p<image->pins.size(); ++p )
|
||||
{
|
||||
PIN* pin = &image->pins[p];
|
||||
|
||||
int netcode = pin->kiNetCode;
|
||||
if( netcode > 0 )
|
||||
{
|
||||
NET* net = nets[netcode];
|
||||
|
||||
net->pins.push_back( empty );
|
||||
|
||||
PIN_REF& pin_ref = net->pins.back();
|
||||
|
||||
pin_ref.component_id = CONV_TO_UTF8( module->GetReference() );
|
||||
pin_ref.pin_id = pin->pin_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IMAGE* registered = pcb->library->LookupIMAGE( image );
|
||||
if( registered != image )
|
||||
{
|
||||
// If our new 'image' is not a unique IMAGE, delete it.
|
||||
// In either case, 'registered' is the one we'll work with henceforth.
|
||||
// and use the registered one, known as 'image' after this.
|
||||
delete image;
|
||||
image = registered;
|
||||
}
|
||||
|
||||
// @todo: this only works if the user has not modified the MODULE within the PCB
|
||||
// and made it different from what is in the PCBNEW library. Need to test
|
||||
// each image for uniqueness, not just based on name as is done here:
|
||||
|
||||
COMPONENT* comp = pcb->placement->LookupCOMPONENT( registered->GetImageId() );
|
||||
COMPONENT* comp = pcb->placement->LookupCOMPONENT( image->GetImageId() );
|
||||
|
||||
PLACE* place = new PLACE( comp );
|
||||
comp->places.push_back( place );
|
||||
|
@ -1060,69 +1040,73 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
|||
if( module->flag )
|
||||
{
|
||||
int angle = 1800 - module->m_Orient;
|
||||
|
||||
NORMALIZE_ANGLE_POS(angle);
|
||||
|
||||
place->SetRotation( angle/10.0 );
|
||||
|
||||
place->side = T_back;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----<create the nets>------------------------------------------------
|
||||
{
|
||||
NETWORK* network = pcb->network;
|
||||
TYPE_COLLECTOR nets;
|
||||
TYPE_COLLECTOR pads;
|
||||
|
||||
static const KICAD_T scanNETs[] = { PCB_EQUIPOT_STRUCT_TYPE, EOT };
|
||||
|
||||
nets.Collect( aBoard, scanNETs );
|
||||
|
||||
items.Collect( aBoard, scanMODULEs );
|
||||
|
||||
PIN_REF emptypin(0);
|
||||
|
||||
for( int n=0; n<nets.GetCount(); ++n )
|
||||
// copy the SPECCTRA_DB::padstackset to the LIBRARY. Since we are
|
||||
// removing, do not increment the iterator
|
||||
for( PADSTACKSET::iterator i=padstackset.begin(); i!=padstackset.end();
|
||||
i=padstackset.begin() )
|
||||
{
|
||||
EQUIPOT* kinet = (EQUIPOT*) nets[n];
|
||||
PADSTACKSET::auto_type ps = padstackset.release( i );
|
||||
PADSTACK* padstack = ps.release();
|
||||
|
||||
if( kinet->GetNet() == 0 )
|
||||
continue;
|
||||
pcb->library->AddPadstack( padstack );
|
||||
}
|
||||
|
||||
NET* net = new NET( network );
|
||||
network->nets.push_back( net );
|
||||
|
||||
net->net_id = CONV_TO_UTF8( kinet->m_Netname );
|
||||
net->net_number = kinet->GetNet();
|
||||
|
||||
for( int m=0; m<items.GetCount(); ++m )
|
||||
// copy our SPECCTRA_DB::nets to the pcb->network
|
||||
for( unsigned n=1; n<nets.size(); ++n )
|
||||
{
|
||||
NET* net = nets[n];
|
||||
if( net->pins.size() )
|
||||
{
|
||||
MODULE* module = (MODULE*) items[m];
|
||||
|
||||
pads.Collect( module, scanPADs );
|
||||
|
||||
for( int p=0; p<pads.GetCount(); ++p )
|
||||
{
|
||||
D_PAD* pad = (D_PAD*) pads[p];
|
||||
|
||||
if( pad->GetNet() == kinet->GetNet() )
|
||||
{
|
||||
// push on an empty one, then fill it via 'pin_ref'
|
||||
net->pins.push_back( emptypin );
|
||||
PIN_REF* pin_ref = &net->pins.back();
|
||||
|
||||
pin_ref->SetParent( net );
|
||||
pin_ref->component_id = CONV_TO_UTF8( module->GetReference() );
|
||||
pin_ref->pin_id = CONV_TO_UTF8( pad->ReturnStringPadName() );
|
||||
}
|
||||
}
|
||||
// give ownership to pcb->network
|
||||
pcb->network->nets.push_back( net );
|
||||
nets[n] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----< output the vias >-----------------------------------------------
|
||||
{
|
||||
// ASSUME: unique pads are now in the padstack list! i.e. this code
|
||||
// must follow the initial padstack construction code.
|
||||
// Next we add the via's which may be used.
|
||||
|
||||
int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize;
|
||||
if( defaultViaSize )
|
||||
{
|
||||
PADSTACK* padstack = makeVia( defaultViaSize, g_DesignSettings.m_ViaDrill,
|
||||
0, aBoard->GetCopperLayerCount()-1 );
|
||||
pcb->library->AddPadstack( padstack );
|
||||
|
||||
// remember this index, it is the default via and also the start of the
|
||||
// vias within the padstack list. Before this index are the pads.
|
||||
// At this index and later are the vias.
|
||||
pcb->library->SetViaStartIndex( pcb->library->padstacks.size()-1 );
|
||||
}
|
||||
|
||||
for( int i=0; i<HISTORY_NUMBER; ++i )
|
||||
{
|
||||
int viaSize = aBoard->m_BoardSettings->m_ViaSizeHistory[i];
|
||||
if( !viaSize )
|
||||
break;
|
||||
|
||||
if( viaSize == defaultViaSize )
|
||||
continue;
|
||||
|
||||
PADSTACK* padstack = makeVia( viaSize, g_DesignSettings.m_ViaDrill,
|
||||
0, aBoard->GetCopperLayerCount()-1 );
|
||||
pcb->library->AddPadstack( padstack );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1 // do existing wires and vias
|
||||
|
||||
//-----<create the wires from tracks>-----------------------------------
|
||||
|
|
Loading…
Reference in New Issue