Commit 709be495 authored by dickelbeck's avatar dickelbeck

more amazing free specctra work

parent 10ded82d
......@@ -5,6 +5,15 @@ 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
================================================================================
......@@ -18,7 +27,7 @@ email address.
** 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
......
......@@ -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 )
{
......
......@@ -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 )
{
......@@ -468,6 +478,8 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
{
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,7 +2243,8 @@ void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
growth->padstack_id = lexer->CurText();
tok = nextTok();
while( (tok = nextTok()) != T_RIGHT )
{
if( tok == T_LEFT )
{
tok = nextTok();
......@@ -2230,9 +2255,9 @@ void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
expecting( T_NUMBER );
growth->SetRotation( strtod( lexer->CurText(), 0 ) );
needRIGHT();
tok = nextTok();
}
else
{
if( !isSymbol(tok) && tok!=T_NUMBER )
expecting( "pin_id" );
......@@ -2245,9 +2270,8 @@ void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
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;
......@@ -2308,6 +2332,7 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
{
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 );
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment