more free specctra work
This commit is contained in:
parent
7878ba2726
commit
67ebe29b60
|
@ -1,5 +1,4 @@
|
|||
|
||||
|
||||
Change Log for Kicad
|
||||
Started 2007-June-11
|
||||
|
||||
|
@ -16,7 +15,6 @@ email address.
|
|||
the new track takes the width of the existing track
|
||||
|
||||
|
||||
|
||||
2008-Jan-27 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
+all:
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include <wx/ffile.h>
|
||||
|
||||
|
||||
// To build the DSN beautifier and unit tester, simply uncomment this and then
|
||||
// use CMake's makefile to build target "specctra_test".
|
||||
//#define STANDALONE // define "stand alone, i.e. unit testing"
|
||||
|
||||
|
||||
|
@ -861,24 +863,32 @@ void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IOError )
|
|||
switch( tok )
|
||||
{
|
||||
case T_rect:
|
||||
growth->rectangle = new RECTANGLE( growth );
|
||||
doRECTANGLE( growth->rectangle );
|
||||
if( growth->shape )
|
||||
unexpected( tok );
|
||||
growth->shape = new RECTANGLE( growth );
|
||||
doRECTANGLE( (RECTANGLE*) growth->shape );
|
||||
break;
|
||||
|
||||
case T_circle:
|
||||
growth->circle = new CIRCLE( growth );
|
||||
doCIRCLE( growth->circle );
|
||||
if( growth->shape )
|
||||
unexpected( tok );
|
||||
growth->shape = new CIRCLE( growth );
|
||||
doCIRCLE( (CIRCLE*) growth->shape );
|
||||
break;
|
||||
|
||||
case T_path:
|
||||
case T_polygon:
|
||||
growth->path = new PATH( growth, tok );
|
||||
doPATH( growth->path );
|
||||
if( growth->shape )
|
||||
unexpected( tok );
|
||||
growth->shape = new PATH( growth, tok );
|
||||
doPATH( (PATH*) growth->shape );
|
||||
break;
|
||||
|
||||
case T_qarc:
|
||||
growth->qarc = new QARC( growth );
|
||||
doQARC( growth->qarc );
|
||||
if( growth->shape )
|
||||
unexpected( tok );
|
||||
growth->shape = new QARC( growth );
|
||||
doQARC( (QARC*) growth->shape );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3353,18 +3363,19 @@ int SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
|
|||
return total;
|
||||
}
|
||||
|
||||
// factor out a common GetQuoteChar
|
||||
|
||||
const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
|
||||
const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote_char )
|
||||
{
|
||||
// I include '#' so a symbol is not confused with a comment. We intend
|
||||
// to wrap any symbol starting with a '#'.
|
||||
// Our LEXER class handles comments, and comments appear to be an extension
|
||||
// to the SPECCTRA DSN specification.
|
||||
if( *wrapee == '#' )
|
||||
return quote_char.c_str();
|
||||
return quote_char;
|
||||
|
||||
if( strlen(wrapee)==0 )
|
||||
return quote_char.c_str();
|
||||
return quote_char;
|
||||
|
||||
bool isNumber = true;
|
||||
|
||||
|
@ -3373,19 +3384,25 @@ const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
|
|||
// if the string to be wrapped (wrapee) has a delimiter in it,
|
||||
// return the quote_char so caller wraps the wrapee.
|
||||
if( strchr( "\t ()", *wrapee ) )
|
||||
return quote_char.c_str();
|
||||
return quote_char;
|
||||
|
||||
if( !strchr( "01234567890.-+", *wrapee ) )
|
||||
isNumber = false;
|
||||
}
|
||||
|
||||
if( isNumber )
|
||||
return quote_char.c_str();
|
||||
return quote_char;
|
||||
|
||||
return ""; // can use an unwrapped string.
|
||||
}
|
||||
|
||||
|
||||
const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
|
||||
{
|
||||
return OUTPUTFORMATTER::GetQuoteChar( wrapee, quote_char.c_str() );
|
||||
}
|
||||
|
||||
|
||||
void SPECCTRA_DB::ExportPCB( wxString filename, bool aNameChange ) throw( IOError )
|
||||
{
|
||||
fp = wxFopen( filename, wxT("w") );
|
||||
|
@ -3438,6 +3455,8 @@ PCB* SPECCTRA_DB::MakePCB()
|
|||
|
||||
pcb->structure = new STRUCTURE( pcb );
|
||||
pcb->structure->boundary = new BOUNDARY( pcb->structure );
|
||||
pcb->structure->via = new VIA( pcb->structure );
|
||||
pcb->structure->rules = new RULE( pcb->structure, T_rule );
|
||||
|
||||
pcb->placement = new PLACEMENT( pcb );
|
||||
|
||||
|
@ -3451,6 +3470,87 @@ PCB* SPECCTRA_DB::MakePCB()
|
|||
}
|
||||
|
||||
|
||||
//-----<STRINGFORMATTER>----------------------------------------------------
|
||||
|
||||
const char* STRINGFORMATTER::GetQuoteChar( const char* wrapee )
|
||||
{
|
||||
// for what we are using STRINGFORMATTER for at this time, we can return the nul string
|
||||
// always.
|
||||
|
||||
return "";
|
||||
// return OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, "\"" );
|
||||
}
|
||||
|
||||
int STRINGFORMATTER::vprint( const char* fmt, va_list ap )
|
||||
{
|
||||
int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
|
||||
if( ret >= (int) buffer.size() )
|
||||
{
|
||||
buffer.reserve( ret+200 );
|
||||
ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
|
||||
}
|
||||
|
||||
if( ret > 0 )
|
||||
mystring.append( (const char*) &buffer[0] );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int STRINGFORMATTER::sprint( const char* fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, fmt );
|
||||
int ret = vprint( fmt, args);
|
||||
va_end( args );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, fmt );
|
||||
|
||||
int result = 0;
|
||||
int total = 0;
|
||||
|
||||
for( int i=0; i<nestLevel; ++i )
|
||||
{
|
||||
result = sprint( "%*c", NESTWIDTH, ' ' );
|
||||
if( result < 0 )
|
||||
break;
|
||||
|
||||
total += result;
|
||||
}
|
||||
|
||||
if( result<0 || (result=vprint( fmt, args ))<0 )
|
||||
{
|
||||
throw IOError( _("Error writing to STRINGFORMATTER") );
|
||||
}
|
||||
|
||||
va_end( args );
|
||||
|
||||
total += result;
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
void STRINGFORMATTER::StripUseless()
|
||||
{
|
||||
for( std::string::iterator i=mystring.begin(); i!=mystring.end(); )
|
||||
{
|
||||
if( isspace( *i ) || *i==')' || *i=='(' )
|
||||
mystring.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----<ELEM>---------------------------------------------------------------
|
||||
|
||||
ELEM::ELEM( DSN_T aType, ELEM* aParent ) :
|
||||
|
@ -3500,8 +3600,40 @@ int ELEM_HOLDER::FindElem( DSN_T aType, int instanceNum )
|
|||
}
|
||||
|
||||
|
||||
//-----<PARSER>-----------------------------------------------------------
|
||||
//-----<PADSTACK>---------------------------------------------------------
|
||||
|
||||
int PADSTACK::Compare( PADSTACK* lhs, PADSTACK* rhs )
|
||||
{
|
||||
if( !lhs->hash.size() )
|
||||
lhs->hash = lhs->makeHash();
|
||||
|
||||
if( !rhs->hash.size() )
|
||||
rhs->hash = rhs->makeHash();
|
||||
|
||||
int result = lhs->hash.compare( rhs->hash );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----<IMAGE>------------------------------------------------------------
|
||||
|
||||
int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
|
||||
{
|
||||
if( !lhs->hash.size() )
|
||||
lhs->hash = lhs->makeHash();
|
||||
|
||||
if( !rhs->hash.size() )
|
||||
rhs->hash = rhs->makeHash();
|
||||
|
||||
int result = lhs->hash.compare( rhs->hash );
|
||||
|
||||
// printf("\"%s\" \"%s\" ret=%d\n", lhs->hash.c_str(), rhs->hash.c_str(), result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----<PARSER>-----------------------------------------------------------
|
||||
|
||||
PARSER::PARSER( ELEM* aParent ) :
|
||||
ELEM( T_parser, aParent )
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "fctsys.h"
|
||||
#include "dsn.h"
|
||||
|
||||
class TYPE_COLLECTOR; // outside the DSN namespace
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -101,9 +103,86 @@ public:
|
|||
* if the wrapee does not need to be wrapped.
|
||||
*/
|
||||
virtual const char* GetQuoteChar( const char* wrapee ) = 0;
|
||||
};
|
||||
|
||||
|
||||
virtual ~OUTPUTFORMATTER() {}
|
||||
|
||||
/**
|
||||
* Function GetQuoteChar
|
||||
* factor may be used by derived classes to perform quote character selection.
|
||||
* @param wrapee A string that might need wrapping on each end.
|
||||
* @param quote_char A single character C string which hold the current quote character.
|
||||
* @return const char* - the quote_char as a single character string, or ""
|
||||
* if the wrapee does not need to be wrapped.
|
||||
*/
|
||||
static const char* GetQuoteChar( const char* wrapee, const char* quote_char );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class STRINGFORMATTER
|
||||
* implements OUTPUTFORMATTER to a memory buffer. After Print()ing the
|
||||
* string is available through GetString()
|
||||
*/
|
||||
class STRINGFORMATTER : public OUTPUTFORMATTER
|
||||
{
|
||||
std::vector<char> buffer;
|
||||
std::string mystring;
|
||||
|
||||
int sprint( const char* fmt, ... );
|
||||
int vprint( const char* fmt, va_list ap );
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor STRINGFORMATTER
|
||||
* reserves space in the buffer
|
||||
*/
|
||||
STRINGFORMATTER( int aReserve = 300 ) :
|
||||
buffer( aReserve, '\0' )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Clear
|
||||
* clears the buffer and empties the internal string.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
mystring.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function StripUseless
|
||||
* removes whitespace, '(', and ')' from the mystring.
|
||||
*/
|
||||
void StripUseless();
|
||||
|
||||
/*
|
||||
const char* c_str()
|
||||
{
|
||||
return mystring.c_str();
|
||||
}
|
||||
*/
|
||||
|
||||
std::string GetString()
|
||||
{
|
||||
return mystring;
|
||||
}
|
||||
|
||||
|
||||
//-----<OUTPUTFORMATTER>------------------------------------------------
|
||||
int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError );
|
||||
const char* GetQuoteChar( const char* wrapee );
|
||||
//-----</OUTPUTFORMATTER>-----------------------------------------------
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class POINT
|
||||
* is a holder for a point in the SPECCTRA DSN coordinate system. It can also
|
||||
* be used to hold a distance (vector really) from some origin.
|
||||
*/
|
||||
struct POINT
|
||||
{
|
||||
double x;
|
||||
|
@ -136,14 +215,23 @@ struct POINT
|
|||
POINT& operator=( const POINT& other )
|
||||
{
|
||||
x = other.x;
|
||||
if( x == -0.0 ) // correct -0.0 so output looks nice.
|
||||
x = 0.0;
|
||||
y = other.y;
|
||||
if( y == -0.0 )
|
||||
y = 0.0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function FixNegativeZero
|
||||
* will change negative zero to positive zero in the IEEE floating point
|
||||
* storage format. Basically turns off the sign bit if the mantiss and exponent
|
||||
* would say the value is zero.
|
||||
*/
|
||||
void FixNegativeZero()
|
||||
{
|
||||
if( x == -0.0 )
|
||||
x = 0.0;
|
||||
if( y == -0.0 )
|
||||
y = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
|
@ -196,10 +284,33 @@ typedef std::vector<PROPERTY> PROPERTIES;
|
|||
class ELEM
|
||||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
DSN_T type;
|
||||
ELEM* parent;
|
||||
|
||||
|
||||
/**
|
||||
* Function makeHash
|
||||
* returns a string which uniquely represents this ELEM amoung other
|
||||
* ELEMs of the same derived class as "this" one.
|
||||
* It is not useable for all derived classes, only those which plan for
|
||||
* it by implementing a FormatContents() function that captures all info
|
||||
* which will be used in the subsequent string compare. THIS SHOULD
|
||||
* NORMALLY EXCLUDE THE TYPENAME, AND INSTANCE NAME OR ID AS WELL.
|
||||
*/
|
||||
std::string makeHash()
|
||||
{
|
||||
STRINGFORMATTER sf;
|
||||
|
||||
FormatContents( &sf, 0 );
|
||||
sf.StripUseless();
|
||||
|
||||
return sf.GetString();
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -207,7 +318,7 @@ public:
|
|||
|
||||
virtual ~ELEM();
|
||||
|
||||
DSN_T Type() { return type; }
|
||||
DSN_T Type() const { return type; }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -216,7 +327,7 @@ public:
|
|||
* to check for section specific overrides.
|
||||
* @return DSN_T - one of the allowed values to <unit_descriptor>
|
||||
*/
|
||||
virtual DSN_T GetUnits()
|
||||
virtual DSN_T GetUnits() const
|
||||
{
|
||||
if( parent )
|
||||
return parent->GetUnits();
|
||||
|
@ -324,14 +435,14 @@ public:
|
|||
kids.insert( kids.begin()+aIndex, aElem );
|
||||
}
|
||||
|
||||
ELEM* At( int aIndex )
|
||||
ELEM* At( int aIndex ) const
|
||||
{
|
||||
// we have varying sized objects and are using polymorphism, so we
|
||||
// must return a pointer not a reference.
|
||||
return &kids[aIndex];
|
||||
return (ELEM*) &kids[aIndex];
|
||||
}
|
||||
|
||||
ELEM* operator[]( int aIndex )
|
||||
ELEM* operator[]( int aIndex ) const
|
||||
{
|
||||
return At( aIndex );
|
||||
}
|
||||
|
@ -408,7 +519,7 @@ public:
|
|||
LEXER::GetTokenText(units), value );
|
||||
}
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
return units;
|
||||
}
|
||||
|
@ -439,7 +550,10 @@ public:
|
|||
void SetCorners( const POINT& aPoint0, const POINT& aPoint1 )
|
||||
{
|
||||
point0 = aPoint0;
|
||||
point0.FixNegativeZero();
|
||||
|
||||
point1 = aPoint1;
|
||||
point1.FixNegativeZero();
|
||||
}
|
||||
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
|
@ -581,7 +695,6 @@ public:
|
|||
out->Print( nestLevel, ")\n" );
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::ptr_vector<LAYER_RULE> LAYER_RULES;
|
||||
|
||||
|
||||
|
@ -780,15 +893,21 @@ public:
|
|||
}
|
||||
void SetStart( const POINT& aStart )
|
||||
{
|
||||
vertex[0] = aStart;
|
||||
vertex[0] = aStart;
|
||||
// no -0.0 on the printouts!
|
||||
vertex[0].FixNegativeZero();
|
||||
}
|
||||
void SetEnd( const POINT& aEnd )
|
||||
{
|
||||
vertex[1] = aEnd;
|
||||
// no -0.0 on the printouts!
|
||||
vertex[1].FixNegativeZero();
|
||||
}
|
||||
void SetCenter( const POINT& aCenter )
|
||||
{
|
||||
vertex[2] = aCenter;
|
||||
// no -0.0 on the printouts!
|
||||
vertex[2].FixNegativeZero();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -797,49 +916,53 @@ class WINDOW : public ELEM
|
|||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
//----- only one of these is used, like a union -----
|
||||
protected:
|
||||
/* shape holds one of these
|
||||
PATH* path; ///< used for both path and polygon
|
||||
RECTANGLE* rectangle;
|
||||
CIRCLE* circle;
|
||||
QARC* qarc;
|
||||
//---------------------------------------------------
|
||||
|
||||
*/
|
||||
ELEM* shape;
|
||||
|
||||
public:
|
||||
|
||||
WINDOW( ELEM* aParent ) :
|
||||
ELEM( T_window, aParent )
|
||||
WINDOW( ELEM* aParent, DSN_T aType = T_window ) :
|
||||
ELEM( aType, aParent )
|
||||
{
|
||||
path = 0;
|
||||
rectangle = 0;
|
||||
circle = 0;
|
||||
qarc = 0;
|
||||
shape = 0;
|
||||
}
|
||||
|
||||
~WINDOW()
|
||||
{
|
||||
delete path;
|
||||
delete rectangle;
|
||||
delete circle;
|
||||
delete qarc;
|
||||
delete shape;
|
||||
}
|
||||
|
||||
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
// these are mutually exclusive
|
||||
if( rectangle )
|
||||
rectangle->Format( out, nestLevel );
|
||||
|
||||
else if( path )
|
||||
path->Format( out, nestLevel );
|
||||
|
||||
else if( circle )
|
||||
circle->Format( out, nestLevel );
|
||||
|
||||
else if( qarc )
|
||||
qarc->Format( out, nestLevel );
|
||||
void SetShape( ELEM* aShape )
|
||||
{
|
||||
delete shape;
|
||||
shape = aShape;
|
||||
|
||||
if( aShape )
|
||||
{
|
||||
wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle
|
||||
|| aShape->Type()==T_qarc || aShape->Type()==T_path
|
||||
|| aShape->Type()==T_polygon);
|
||||
|
||||
aShape->SetParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
out->Print( nestLevel, "(%s ", LEXER::GetTokenText( Type() ) );
|
||||
|
||||
if( shape )
|
||||
shape->Format( out, 0 );
|
||||
|
||||
out->Print( 0, ")\n" );
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::ptr_vector<WINDOW> WINDOWS;
|
||||
|
||||
|
||||
|
@ -956,6 +1079,11 @@ public:
|
|||
ELEM( T_via, aParent )
|
||||
{
|
||||
}
|
||||
|
||||
void AppendVia( const char* aViaName )
|
||||
{
|
||||
padstacks.push_back( aViaName );
|
||||
}
|
||||
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
|
@ -1217,13 +1345,13 @@ public:
|
|||
layer_weight );
|
||||
}
|
||||
};
|
||||
typedef boost::ptr_vector<LAYER_PAIR> LAYER_PAIRS;
|
||||
|
||||
|
||||
class LAYER_NOISE_WEIGHT : public ELEM
|
||||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
typedef boost::ptr_vector<LAYER_PAIR> LAYER_PAIRS;
|
||||
LAYER_PAIRS layer_pairs;
|
||||
|
||||
public:
|
||||
|
@ -1542,7 +1670,7 @@ public:
|
|||
i->Format( out, nestLevel );
|
||||
}
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
@ -1693,7 +1821,7 @@ public:
|
|||
i->Format( out, nestLevel );
|
||||
}
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
@ -1710,7 +1838,7 @@ public:
|
|||
* elements contains, i.e. in its "shape" field. This class also implements
|
||||
* the "(outline ...)" element as a dual personality.
|
||||
*/
|
||||
class SHAPE : public ELEM
|
||||
class SHAPE : public WINDOW
|
||||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
|
@ -1722,38 +1850,18 @@ class SHAPE : public ELEM
|
|||
<polygon_descriptor> |
|
||||
<path_descriptor> |
|
||||
<qarc_descriptor> ]
|
||||
ELEM* shape; // inherited from WINDOW
|
||||
*/
|
||||
ELEM* shape;
|
||||
|
||||
|
||||
WINDOWS windows;
|
||||
|
||||
public:
|
||||
SHAPE( ELEM* aParent, DSN_T aType = T_shape ) :
|
||||
ELEM( aType, aParent )
|
||||
WINDOW( aParent, aType )
|
||||
{
|
||||
connect = T_on;
|
||||
shape = 0;
|
||||
}
|
||||
~SHAPE()
|
||||
{
|
||||
delete shape;
|
||||
}
|
||||
|
||||
void SetShape( ELEM* aShape )
|
||||
{
|
||||
delete shape;
|
||||
shape = aShape;
|
||||
|
||||
if( aShape )
|
||||
{
|
||||
wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle
|
||||
|| aShape->Type()==T_qarc || aShape->Type()==T_path
|
||||
|| aShape->Type()==T_polygon);
|
||||
|
||||
aShape->SetParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
void SetConnect( DSN_T aConnect )
|
||||
{
|
||||
connect = aConnect;
|
||||
|
@ -1808,6 +1916,12 @@ public:
|
|||
isRotated = (aRotation != 0.0);
|
||||
}
|
||||
|
||||
void SetVertex( const POINT& aPoint )
|
||||
{
|
||||
vertex = aPoint;
|
||||
vertex.FixNegativeZero();
|
||||
}
|
||||
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
const char* quote = out->GetQuoteChar( padstack_id.c_str() );
|
||||
|
@ -1830,6 +1944,8 @@ class IMAGE : public ELEM_HOLDER
|
|||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
|
||||
|
||||
std::string image_id;
|
||||
DSN_T side;
|
||||
UNIT_RES* unit;
|
||||
|
@ -1864,42 +1980,53 @@ public:
|
|||
delete place_rules;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Compare
|
||||
* compares two objects of this type and returns <0, 0, or >0.
|
||||
*/
|
||||
static int Compare( IMAGE* lhs, IMAGE* rhs );
|
||||
|
||||
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
const char* quote = out->GetQuoteChar( image_id.c_str() );
|
||||
|
||||
out->Print( nestLevel, "(%s %s%s%s", LEXER::GetTokenText( Type() ),
|
||||
quote, image_id.c_str(), quote );
|
||||
|
||||
FormatContents( out, nestLevel+1 );
|
||||
|
||||
out->Print( nestLevel, ")\n" );
|
||||
}
|
||||
|
||||
// this is here for makeHash()
|
||||
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
if( side != T_both )
|
||||
out->Print( 0, " (side %s)", LEXER::GetTokenText( side ) );
|
||||
|
||||
out->Print( 0, "\n");
|
||||
|
||||
if( unit )
|
||||
unit->Format( out, nestLevel+1 );
|
||||
unit->Format( out, nestLevel );
|
||||
|
||||
// format the kids, which in this class are the shapes
|
||||
ELEM_HOLDER::FormatContents( out, nestLevel+1 );
|
||||
ELEM_HOLDER::FormatContents( out, nestLevel );
|
||||
|
||||
for( PINS::iterator i=pins.begin(); i!=pins.end(); ++i )
|
||||
i->Format( out, nestLevel+1 );
|
||||
i->Format( out, nestLevel );
|
||||
|
||||
if( rules )
|
||||
rules->Format( out, nestLevel+1 );
|
||||
rules->Format( out, nestLevel );
|
||||
|
||||
if( place_rules )
|
||||
place_rules->Format( out, nestLevel+1 );
|
||||
place_rules->Format( out, nestLevel );
|
||||
|
||||
for( KEEPOUTS::iterator i=keepouts.begin(); i!=keepouts.end(); ++i )
|
||||
i->Format( out, nestLevel+1 );
|
||||
|
||||
out->Print( nestLevel, ")\n" );
|
||||
i->Format( out, nestLevel );
|
||||
}
|
||||
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
@ -1907,12 +2034,20 @@ public:
|
|||
return ELEM::GetUnits();
|
||||
}
|
||||
};
|
||||
typedef boost::ptr_vector<IMAGE> IMAGES;
|
||||
|
||||
|
||||
/**
|
||||
* Class PADSTACK
|
||||
* holds either a via or a pad definition.
|
||||
*/
|
||||
class PADSTACK : public ELEM_HOLDER
|
||||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
|
||||
|
||||
|
||||
std::string padstack_id;
|
||||
UNIT_RES* unit;
|
||||
|
||||
|
@ -1942,6 +2077,13 @@ public:
|
|||
delete rules;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Compare
|
||||
* compares two objects of this type and returns <0, 0, or >0.
|
||||
*/
|
||||
static int Compare( PADSTACK* lhs, PADSTACK* rhs );
|
||||
|
||||
void SetPadstackId( const char* aPadstackId )
|
||||
{
|
||||
padstack_id = aPadstackId;
|
||||
|
@ -1954,11 +2096,20 @@ public:
|
|||
out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ),
|
||||
quote, padstack_id.c_str(), quote );
|
||||
|
||||
FormatContents( out, nestLevel+1 );
|
||||
|
||||
out->Print( nestLevel, ")\n" );
|
||||
}
|
||||
|
||||
|
||||
// this factored out for use by Compare()
|
||||
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
if( unit )
|
||||
unit->Format( out, nestLevel+1 );
|
||||
unit->Format( out, nestLevel );
|
||||
|
||||
// format the kids, which in this class are the shapes
|
||||
ELEM_HOLDER::FormatContents( out, nestLevel+1 );
|
||||
ELEM_HOLDER::FormatContents( out, nestLevel );
|
||||
|
||||
out->Print( nestLevel+1, "%s", "" );
|
||||
|
||||
|
@ -1982,12 +2133,11 @@ public:
|
|||
out->Print( 0, "\n" );
|
||||
|
||||
if( rules )
|
||||
rules->Format( out, nestLevel+1 );
|
||||
|
||||
out->Print( nestLevel, ")\n" );
|
||||
rules->Format( out, nestLevel );
|
||||
}
|
||||
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
@ -2007,25 +2157,68 @@ typedef boost::ptr_vector<PADSTACK> PADSTACKS;
|
|||
class LIBRARY : public ELEM
|
||||
{
|
||||
friend class SPECCTRA_DB;
|
||||
|
||||
UNIT_RES* unit;
|
||||
|
||||
typedef boost::ptr_vector<IMAGE> IMAGES;
|
||||
UNIT_RES* unit;
|
||||
IMAGES images;
|
||||
|
||||
PADSTACKS padstacks;
|
||||
|
||||
/// The start of the vias within the padstacks, which trail the pads.
|
||||
/// This field is not Format()ed.
|
||||
int via_start_index;
|
||||
|
||||
public:
|
||||
|
||||
LIBRARY( ELEM* aParent, DSN_T aType = T_library ) :
|
||||
ELEM( aType, aParent )
|
||||
{
|
||||
unit = 0;
|
||||
via_start_index = -1; // 0 or greater means there is at least one via
|
||||
}
|
||||
~LIBRARY()
|
||||
{
|
||||
delete unit;
|
||||
}
|
||||
|
||||
void AddPadstack( PADSTACK* aPadstack )
|
||||
{
|
||||
padstacks.push_back( aPadstack );
|
||||
}
|
||||
|
||||
void SetViaStartIndex( int aIndex )
|
||||
{
|
||||
via_start_index = aIndex;
|
||||
}
|
||||
int GetViaStartIndex()
|
||||
{
|
||||
return via_start_index;
|
||||
}
|
||||
|
||||
int FindIMAGE( IMAGE* aImage )
|
||||
{
|
||||
for( unsigned i=0; i<images.size(); ++i )
|
||||
{
|
||||
if( 0 == IMAGE::Compare( aImage, &images[i] ) )
|
||||
return (int) i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void AppendIMAGE( IMAGE* aImage )
|
||||
{
|
||||
aImage->SetParent( this );
|
||||
images.push_back( aImage );
|
||||
}
|
||||
|
||||
bool LookupIMAGE( IMAGE* aImage )
|
||||
{
|
||||
int ndx = FindIMAGE( aImage );
|
||||
if( ndx == -1 )
|
||||
{
|
||||
AppendIMAGE( aImage );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
|
@ -2039,18 +2232,13 @@ public:
|
|||
i->Format( out, nestLevel );
|
||||
}
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
||||
return ELEM::GetUnits();
|
||||
}
|
||||
|
||||
void AddPadstack( PADSTACK* aPadstack )
|
||||
{
|
||||
padstacks.push_back( aPadstack );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2422,6 +2610,8 @@ public:
|
|||
|
||||
class CONNECT : public ELEM
|
||||
{
|
||||
// @todo not completed.
|
||||
|
||||
public:
|
||||
CONNECT( ELEM* parent ) :
|
||||
ELEM( T_connect, parent ) {}
|
||||
|
@ -2695,7 +2885,7 @@ public:
|
|||
i->Format( out, nestLevel );
|
||||
}
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
@ -2780,7 +2970,7 @@ public:
|
|||
out->Print( nestLevel, ")\n" );
|
||||
}
|
||||
|
||||
DSN_T GetUnits()
|
||||
DSN_T GetUnits() const
|
||||
{
|
||||
if( unit )
|
||||
return unit->GetUnits();
|
||||
|
@ -3179,6 +3369,8 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
wxString filename;
|
||||
|
||||
std::string quote_char;
|
||||
|
||||
STRINGFORMATTER sf;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -3321,6 +3513,22 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
void doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IOError );
|
||||
|
||||
|
||||
/**
|
||||
* Function makeIMAGE
|
||||
* allocates an IMAGE on the heap and creates all the PINs according
|
||||
* to the PADs in the MODULE.
|
||||
*/
|
||||
IMAGE* makeIMAGE( MODULE* aModule );
|
||||
|
||||
|
||||
/**
|
||||
* Function makePADSTACKs
|
||||
* makes all the PADSTACKs, and marks each D_PAD with the index into the
|
||||
* LIBRARY::padstacks list that it matches.
|
||||
*/
|
||||
void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads );
|
||||
|
||||
|
||||
public:
|
||||
|
||||
SPECCTRA_DB()
|
||||
|
@ -3332,7 +3540,7 @@ public:
|
|||
quote_char += '"';
|
||||
}
|
||||
|
||||
~SPECCTRA_DB()
|
||||
virtual ~SPECCTRA_DB()
|
||||
{
|
||||
delete lexer;
|
||||
delete pcb;
|
||||
|
|
|
@ -234,14 +234,43 @@ static QARC* makeArc( const POINT& aStart, const POINT& aEnd,
|
|||
qarc->SetLayerId( aLayerName.c_str() );
|
||||
return qarc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function makePADSTACKs
|
||||
* makes all the PADSTACKs, and marks each D_PAD with the index into the
|
||||
* LIBRARY::padstacks list that it matches.
|
||||
*/
|
||||
static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibrary )
|
||||
|
||||
IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
|
||||
{
|
||||
TYPE_COLLECTOR items;
|
||||
|
||||
static const KICAD_T scanPADs[] = { TYPEPAD, EOT };
|
||||
|
||||
PADSTACKS& padstacks = pcb->library->padstacks;
|
||||
|
||||
// get all the MODULE's pads.
|
||||
items.Collect( aModule, scanPADs );
|
||||
|
||||
IMAGE* image = new IMAGE( 0 );
|
||||
|
||||
image->image_id = CONV_TO_UTF8( aModule->m_LibRef );
|
||||
|
||||
// collate all the pads, and make a component.
|
||||
for( int p=0; p<items.GetCount(); ++p )
|
||||
{
|
||||
D_PAD* pad = (D_PAD*) items[p];
|
||||
|
||||
PADSTACK* padstack = &padstacks[pad->m_logical_connexion];
|
||||
|
||||
PIN* pin = new PIN(image);
|
||||
image->pins.push_back( pin );
|
||||
|
||||
pin->padstack_id = padstack->padstack_id;
|
||||
pin->pin_id = CONV_TO_UTF8( pad->ReturnStringPadName() );
|
||||
pin->SetVertex( mapPt( pad->m_Pos0 ) );
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
|
||||
{
|
||||
char name[80]; // padstack name builder
|
||||
|
||||
|
@ -251,7 +280,6 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
}
|
||||
|
||||
D_PAD* old_pad = NULL;
|
||||
int padstackNdx = 0;
|
||||
|
||||
#define COPPER_LAYERS 2 // top and bottom
|
||||
|
||||
|
@ -262,7 +290,7 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
// within a pad's padstack. this is usually correct, but not rigorous. 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
|
||||
// See page bottom of page 74 of the SECCTRA Design Language Reference, May 2000.
|
||||
// See bottom of page 74 of the SECCTRA Design Language Reference, May 2000.
|
||||
|
||||
std::string layerId[COPPER_LAYERS] = {
|
||||
CONV_TO_UTF8(aBoard->GetLayerName( LAYER_CMP_N )),
|
||||
|
@ -270,8 +298,9 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
};
|
||||
|
||||
#if 1
|
||||
// late breaking news, we can use "signal" as the layer name and report the
|
||||
// padstack as a single layer.
|
||||
// Late breaking news: we can use the reserved layer name "signal" and report the
|
||||
// padstack as a single layer. See <reserved_layer_name> in the spec.
|
||||
// But this probably gives problems for a "power" layer or power pin, we'll see.
|
||||
reportedLayers = 1;
|
||||
layerId[0] = "signal";
|
||||
#endif
|
||||
|
@ -280,8 +309,6 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
{
|
||||
D_PAD* pad = (D_PAD*) aPads[i];
|
||||
|
||||
pad->m_logical_connexion = padstackNdx;
|
||||
|
||||
bool doLayer[COPPER_LAYERS] = {
|
||||
pad->IsOnLayer( LAYER_CMP_N ),
|
||||
pad->IsOnLayer( COPPER_LAYER_N )
|
||||
|
@ -289,6 +316,10 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -296,6 +327,9 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
// an "image->keepout" later. No copper pad here, it is probably a hole.
|
||||
if( !doLayer[0] && !doLayer[1] )
|
||||
{
|
||||
// padstacks.size()-1 is the index of the matching padstack in LIBRARY::padstacks
|
||||
pad->m_logical_connexion = pcb->library->padstacks.size()-1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -305,11 +339,11 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
|
||||
old_pad = pad;
|
||||
|
||||
// this is the index into the library->padstacks, be careful.
|
||||
pad->m_logical_connexion = padstackNdx++;
|
||||
|
||||
PADSTACK* padstack = new PADSTACK( aLibrary );
|
||||
aLibrary->AddPadstack( padstack );
|
||||
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;
|
||||
|
||||
// paddOfset is the offset of copper shape relative to hole position,
|
||||
// and pad->m_Pos is hole position. All shapes must be shifted by
|
||||
|
@ -331,12 +365,10 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
{
|
||||
if( doLayer[layer] )
|
||||
{
|
||||
CIRCLE* circle;
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
|
||||
padstack->Append( shape );
|
||||
|
||||
circle = new CIRCLE( shape );
|
||||
CIRCLE* circle = new CIRCLE( shape );
|
||||
shape->SetShape( circle );
|
||||
|
||||
circle->SetLayerId( layerId[layer].c_str() );
|
||||
|
@ -347,7 +379,6 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
}
|
||||
|
||||
snprintf( name, sizeof(name), "Round%dPad_%.6g_mil", coppers, scale(pad->m_Size.x) );
|
||||
|
||||
name[ sizeof(name)-1 ] = 0;
|
||||
|
||||
// @todo verify that all pad names are unique, there is a chance that
|
||||
|
@ -536,9 +567,13 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize;
|
||||
if( defaultViaSize )
|
||||
{
|
||||
PADSTACK* padstack = new PADSTACK( aLibrary );
|
||||
aLibrary->AddPadstack( padstack );
|
||||
padstackNdx++; // remember this index, it is the default via
|
||||
PADSTACK* padstack = new PADSTACK( pcb->library );
|
||||
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 );
|
||||
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
@ -560,9 +595,8 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
if( viaSize == defaultViaSize )
|
||||
continue;
|
||||
|
||||
PADSTACK* padstack = new PADSTACK( aLibrary );
|
||||
aLibrary->AddPadstack( padstack );
|
||||
padstackNdx++; // remember this index, it is the default via
|
||||
PADSTACK* padstack = new PADSTACK( pcb->library );
|
||||
pcb->library->AddPadstack( padstack );
|
||||
|
||||
SHAPE* shape = new SHAPE( padstack );
|
||||
padstack->Append( shape );
|
||||
|
@ -575,10 +609,6 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads, LIBRARY* aLibra
|
|||
snprintf( name, sizeof(name), "Via_%.6g_mil", scale(viaSize) );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
@ -593,7 +623,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
if( !pcb )
|
||||
pcb = SPECCTRA_DB::MakePCB();
|
||||
|
||||
|
||||
// DSN Images (=Kicad MODULES and pads) must be presented from the
|
||||
// top view. So we temporarily flip any modules which are on the back
|
||||
// side of the board to the front, and record this in the MODULE's flag field.
|
||||
|
@ -661,8 +690,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
rect->layer_id = "pcb";
|
||||
|
||||
// opposite corners
|
||||
rect->point0 = ppairs[0].p1;
|
||||
rect->point1 = ppairs[2].p1;
|
||||
rect->SetCorners( ppairs[0].p1, ppairs[2].p1 );
|
||||
|
||||
boundary->rectangle = rect;
|
||||
}
|
||||
|
@ -763,55 +791,61 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
// but in that case they are WINDOWs within the COPPER_PLANEs.
|
||||
|
||||
|
||||
//-----<build the padstack list here, no output>------------------------
|
||||
//-----<build the initial padstack list>--------------------------------
|
||||
{
|
||||
static const KICAD_T scanPADs[] = { TYPEPAD, EOT };
|
||||
|
||||
TYPE_COLLECTOR pads;
|
||||
|
||||
// get all the D_PADs into pads.
|
||||
static const KICAD_T scanPADs[] = { TYPEPAD, EOT };
|
||||
|
||||
// get all the D_PADs into 'pads'.
|
||||
pads.Collect( aBoard, scanPADs );
|
||||
|
||||
makePADSTACKs( aBoard, pads, pcb->library );
|
||||
|
||||
makePADSTACKs( aBoard, pads );
|
||||
|
||||
#if 0 && defined(DEBUG)
|
||||
for( int p=0; p<pads.GetCount(); ++p )
|
||||
pads[p]->Show( 0, std::cout );
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----<via_descriptor>-------------------------------------------------
|
||||
{
|
||||
// Output the vias in the padstack list here, by name
|
||||
}
|
||||
|
||||
|
||||
//-----<build the images>----------------------------------------------
|
||||
{
|
||||
/*
|
||||
static const KICAD_T scanMODULEs[] = { TYPEMODULE, EOT };
|
||||
|
||||
items.Collect( aBoard, scanMODULEs );
|
||||
|
||||
|
||||
for( int m=0; m<items.GetCount(); ++m )
|
||||
{
|
||||
MODULE* module = (MODULE*) items[m];
|
||||
|
||||
// collate all the pads, and make a component.
|
||||
for( int p=0; p<pads.GetCount(); ++p )
|
||||
IMAGE* image = makeIMAGE( module );
|
||||
|
||||
if( pcb->library->LookupIMAGE( image ) )
|
||||
{
|
||||
D_PAD* pad = (D_PAD*) pads[p];
|
||||
|
||||
D(pad->Show( 0, std::cout );)
|
||||
|
||||
// lookup and maybe add this pad to the padstack.
|
||||
wxString padName = lookupPad( pcb->library->padstacks, pad );
|
||||
delete image;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//-----<via_descriptor>-------------------------------------------------
|
||||
{
|
||||
// Output the vias in the padstack list here, by name
|
||||
VIA* vias = pcb->structure->via;
|
||||
PADSTACKS& padstacks = pcb->library->padstacks;
|
||||
int viaNdx = pcb->library->via_start_index;
|
||||
|
||||
if( viaNdx != -1 )
|
||||
{
|
||||
for( ; viaNdx < (int)padstacks.size(); ++viaNdx )
|
||||
{
|
||||
vias->AppendVia( padstacks[viaNdx].padstack_id.c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----<restore MODULEs>------------------------------------------------
|
||||
|
||||
// DSN Images (=Kicad MODULES and pads) must be presented from the
|
||||
// top view. Restore those that were flipped.
|
||||
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
|
||||
|
@ -822,6 +856,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
module->flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue