Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
709be495
Commit
709be495
authored
Feb 14, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more amazing free specctra work
parent
10ded82d
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
657 additions
and
525 deletions
+657
-525
change_log.txt
change_log.txt
+20
-10
class_board_item.cpp
pcbnew/class_board_item.cpp
+48
-47
specctra.cpp
pcbnew/specctra.cpp
+108
-46
specctra.h
pcbnew/specctra.h
+94
-19
specctra_export.cpp
pcbnew/specctra_export.cpp
+387
-403
No files found.
change_log.txt
View file @
709be495
...
...
@@ -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
...
...
pcbnew/class_board_item.cpp
View file @
709be495
...
...
@@ -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
)
{
...
...
pcbnew/specctra.cpp
View file @
709be495
...
...
@@ -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
();
needSYMBOL
orNUMBER
();
growth
->
host_version
=
lexer
->
CurText
();
needRIGHT
();
break
;
case
T_constant
:
needSYMBOL
();
growth
->
const_id
1
=
lexer
->
CurText
();
needSYMBOL
();
growth
->
const_id
2
=
lexer
->
CurText
();
needSYMBOL
orNUMBER
();
const
1
=
lexer
->
CurText
();
needSYMBOL
orNUMBER
();
const
2
=
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_b
ack
(
padstack
);
padstack
=
new
PADSTACK
();
growth
->
AddPadst
ack
(
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
"
,
...
...
pcbnew/specctra.h
View file @
709be495
...
...
@@ -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
);
}
...
...
pcbnew/specctra_export.cpp
View file @
709be495
...
...
@@ -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,246 +314,52 @@ static PATH* makePath( const POINT& aStart, const POINT& aEnd, const std::string
}
IMAGE
*
SPECCTRA_DB
::
makeIMAGE
(
MODULE
*
aModule
)
{
PADSTACKS
&
padstacks
=
pcb
->
library
->
padstacks
;
TYPE_COLLECTOR
pads
;
// get all the MODULE's pads.
pads
.
Collect
(
aModule
,
scanPADs
);
IMAGE
*
image
=
new
IMAGE
(
0
);
image
->
image_id
=
CONV_TO_UTF8
(
aModule
->
m_LibRef
);
// from the pads, and make an IMAGE using collated padstacks.
for
(
int
p
=
0
;
p
<
pads
.
GetCount
();
++
p
)
{
D_PAD
*
pad
=
(
D_PAD
*
)
pads
[
p
];
// 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
);
CIRCLE
*
circle
=
new
CIRCLE
(
keepout
);
keepout
->
SetShape
(
circle
);
circle
->
SetDiameter
(
scale
(
pad
->
m_Drill
.
x
)
);
circle
->
SetVertex
(
mapPt
(
pad
->
m_Pos0
)
);
circle
->
layer_id
=
"signal"
;
}
else
{
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
()
);
wxPoint
pos
(
pad
->
m_Pos0
);
wxPoint
offset
(
pad
->
m_Offset
.
x
,
pad
->
m_Offset
.
y
);
int
angle
=
pad
->
m_Orient
-
aModule
->
m_Orient
;
// tenths of degrees
if
(
angle
)
{
NORMALIZE_ANGLE_POS
(
angle
);
pin
->
SetRotation
(
angle
/
10.0
);
if
(
pad
->
m_Offset
.
x
||
pad
->
m_Offset
.
y
)
{
RotatePoint
(
&
offset
,
angle
);
}
}
pos
+=
offset
;
pin
->
SetVertex
(
mapPt
(
pos
)
);
}
}
return
image
;
}
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
)
{
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
);
double
dsnDiameter
=
scale
(
aCopperDiameter
);
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
(
aDrillDiameter
)
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
padstack
->
SetPadstackId
(
name
);
return
padstack
;
}
/**
* Struct ltWX
* is used secretly by the std:set<> class below. See STRINGSET typedef.
* Struct wxString_less_than_
* is used the std:set<> and std::map<> instantiations below.
* See STRINGSET typedef and PINMAP typedef below.
*/
struct
ltWX
struct
wxString_less_than
{
// a "less than" test on two wxStrings, by pointer.
bool
operator
()(
const
wxString
*
s1
,
const
wxString
*
s2
)
const
bool
operator
()(
const
wxString
&
s1
,
const
wxString
&
s2
)
const
{
return
s1
->
Cmp
(
*
s2
)
<
0
;
// case specific wxString compare
return
s1
.
Cmp
(
s2
)
<
0
;
// case specific wxString compare
}
};
void
SPECCTRA_DB
::
makePADSTACKs
(
BOARD
*
aBoard
,
TYPE_COLLECTOR
&
aPads
)
/**
* 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
;
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
p
ad
->
IsOnLayer
(
LAYER_CMP_N
),
p
ad
->
IsOnLayer
(
COPPER_LAYER_N
)
aP
ad
->
IsOnLayer
(
LAYER_CMP_N
),
aP
ad
->
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
;
// caller must do this screen before calling here.
wxASSERT
(
!
isKeepout
(
aPad
)
);
PADSTACK
*
padstack
=
new
PADSTACK
(
pcb
->
library
);
pcb
->
library
->
AddPadstack
(
padstack
);
wxASSERT
(
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
;
PADSTACK
*
padstack
=
new
PADSTACK
();
/* 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
int
reportedLayers
=
0
;
// 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
)
if
(
aPad
->
m_Attribut
==
PAD_SMD
||
aPad
->
m_Attribut
==
PAD_CONN
)
{
reportedLayers
=
0
;
// PAD_SMD and PAD_CONN are reported on each layer for which
// they are present.
uniqifier
=
'['
;
if
(
doLayer
[
0
]
)
...
...
@@ -568,19 +376,41 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
uniqifier
+=
']'
;
}
else
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
(
p
ad
->
m_PadShape
)
switch
(
aP
ad
->
m_PadShape
)
{
default
:
case
PAD_CIRCLE
:
{
double
diameter
=
scale
(
p
ad
->
m_Size
.
x
);
double
diameter
=
scale
(
aP
ad
->
m_Size
.
x
);
for
(
int
ndx
=
0
;
ndx
<
reportedLayers
;
++
ndx
)
{
...
...
@@ -595,21 +425,16 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
}
snprintf
(
name
,
sizeof
(
name
),
"Round%sPad_%.6g_mil"
,
uniqifier
.
c_str
(),
scale
(
p
ad
->
m_Size
.
x
)
);
uniqifier
.
c_str
(),
scale
(
aP
ad
->
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
(
p
ad
->
m_Size
.
x
)
/
2.0
;
double
dy
=
scale
(
p
ad
->
m_Size
.
y
)
/
2.0
;
double
dx
=
scale
(
aP
ad
->
m_Size
.
x
)
/
2.0
;
double
dy
=
scale
(
aP
ad
->
m_Size
.
y
)
/
2.0
;
POINT
lowerLeft
(
-
dx
,
-
dy
);
POINT
upperRight
(
dx
,
dy
);
...
...
@@ -627,21 +452,17 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
}
snprintf
(
name
,
sizeof
(
name
),
"Rect%sPad_%.6gx%.6g_mil"
,
uniqifier
.
c_str
(),
scale
(
pad
->
m_Size
.
x
),
scale
(
p
ad
->
m_Size
.
y
)
);
uniqifier
.
c_str
(),
scale
(
aPad
->
m_Size
.
x
),
scale
(
aP
ad
->
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
(
p
ad
->
m_Size
.
x
)
/
2.0
;
double
dy
=
scale
(
p
ad
->
m_Size
.
y
)
/
2.0
;
double
dx
=
scale
(
aP
ad
->
m_Size
.
x
)
/
2.0
;
double
dy
=
scale
(
aP
ad
->
m_Size
.
y
)
/
2.0
;
double
dr
=
dx
-
dy
;
if
(
dr
>=
0
)
// oval is horizontal
...
...
@@ -680,13 +501,9 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
}
snprintf
(
name
,
sizeof
(
name
),
"Oval%sPad_%.6gx%.6g_mil"
,
uniqifier
.
c_str
(),
scale
(
pad
->
m_Size
.
x
),
scale
(
p
ad
->
m_Size
.
y
)
);
uniqifier
.
c_str
(),
scale
(
aPad
->
m_Size
.
x
),
scale
(
aP
ad
->
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
;
...
...
@@ -696,40 +513,182 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
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
);
IMAGE
*
image
=
new
IMAGE
(
0
);
image
->
image_id
=
CONV_TO_UTF8
(
aModule
->
m_LibRef
);
// from the pads, and make an IMAGE using collated padstacks.
for
(
int
p
=
0
;
p
<
pads
.
GetCount
();
++
p
)
{
D_PAD
*
pad
=
(
D_PAD
*
)
pads
[
p
];
// see if this pad is a through hole with no copper on its perimeter
if
(
isKeepout
(
pad
)
)
{
double
diameter
=
scale
(
pad
->
m_Drill
.
x
);
POINT
vertex
=
mapPt
(
pad
->
m_Pos0
);
int
layerCount
=
aBoard
->
GetCopperLayerCount
();
for
(
int
layer
=
0
;
layer
<
layerCount
;
++
layer
)
{
KEEPOUT
*
keepout
=
new
KEEPOUT
(
image
,
T_keepout
);
image
->
keepouts
.
push_back
(
keepout
);
CIRCLE
*
circle
=
new
CIRCLE
(
keepout
);
keepout
->
SetShape
(
circle
);
circle
->
SetDiameter
(
diameter
);
circle
->
SetVertex
(
vertex
);
circle
->
SetLayerId
(
layerIds
[
layer
].
c_str
()
);
}
}
else
{
PADSTACK
*
padstack
=
makePADSTACK
(
aBoard
,
pad
);
// unique pads are now in the padstack list.
// next we add the via's which may be used.
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
);
}
int
defaultViaSize
=
aBoard
->
m_BoardSettings
->
m_CurrentViaSize
;
if
(
defaultViaSize
)
PIN
*
pin
=
new
PIN
(
image
);
padName
=
pad
->
ReturnStringPadName
();
pin
->
pin_id
=
CONV_TO_UTF8
(
padName
);
if
(
padName
!=
wxEmptyString
&&
pinmap
.
find
(
padName
)
==
pinmap
.
end
()
)
{
PADSTACK
*
padstack
=
makeVia
(
defaultViaSize
,
g_DesignSettings
.
m_ViaDrill
);
pcb
->
library
->
AddPadstack
(
padstack
);
pinmap
[
padName
]
=
0
;
}
else
{
char
buf
[
32
];
// 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
);
int
duplicates
=
++
pinmap
[
padName
];
sprintf
(
buf
,
"@%d"
,
duplicates
);
// padstack->SetPadstackId( "Via_Default" ); I like the padstack_id with the size in it.
pin
->
pin_id
+=
buf
;
// append "@1" or "@2", etc. to pin name
}
for
(
int
i
=
0
;
i
<
HISTORY_NUMBER
;
++
i
)
pin
->
kiNetCode
=
pad
->
GetNet
();
image
->
pins
.
push_back
(
pin
);
pin
->
padstack_id
=
padstack
->
padstack_id
;
wxPoint
pos
(
pad
->
m_Pos0
);
wxPoint
offset
(
pad
->
m_Offset
.
x
,
pad
->
m_Offset
.
y
);
int
angle
=
pad
->
m_Orient
-
aModule
->
m_Orient
;
// tenths of degrees
if
(
angle
)
{
int
viaSize
=
aBoard
->
m_BoardSettings
->
m_ViaSizeHistory
[
i
];
if
(
!
viaSize
)
break
;
NORMALIZE_ANGLE_POS
(
angle
);
pin
->
SetRotation
(
angle
/
10.0
);
if
(
viaSize
==
defaultViaSize
)
continue
;
if
(
pad
->
m_Offset
.
x
||
pad
->
m_Offset
.
y
)
{
RotatePoint
(
&
offset
,
angle
);
}
}
PADSTACK
*
padstack
=
makeVia
(
viaSize
,
g_DesignSettings
.
m_ViaDrill
);
pcb
->
library
->
AddPadstack
(
padstack
);
pos
+=
offset
;
pin
->
SetVertex
(
mapPt
(
pos
)
);
}
}
return
image
;
}
PADSTACK
*
SPECCTRA_DB
::
makeVia
(
int
aCopperDiameter
,
int
aDrillDiameter
,
int
aTopLayer
,
int
aBotLayer
)
{
char
name
[
48
];
PADSTACK
*
padstack
=
new
PADSTACK
();
double
dsnDiameter
=
scale
(
aCopperDiameter
);
for
(
int
layer
=
aTopLayer
;
layer
<=
aBotLayer
;
++
layer
)
{
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
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
);
return
padstack
;
}
PADSTACK
*
SPECCTRA_DB
::
makeVia
(
const
SEGVIA
*
aVia
)
{
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 )
{
}
#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
)
{
TYPE_COLLECTOR
items
;
...
...
@@ -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.
{
items
.
Collect
(
aBoard
,
scanMODULEs
)
;
TYPE_COLLECTOR
padItems
;
typedef
std
::
set
<
const
wxString
*
,
ltWX
>
STRINGSET
;
typedef
std
::
pair
<
STRINGSET
::
iterator
,
bool
>
PAIR
;
items
.
Collect
(
aBoard
,
scanMODULEs
);
STRINGSET
references
;
// holds unique component reference
s
STRINGSET
refs
;
// holds module reference designator
s
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
(
!
ref
pair
.
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
;
// get all the D_PADs into 'pads'.
pads
.
Collect
(
aBoard
,
scanPADs
);
// 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
()
);
makePADSTACKs
(
aBoard
,
pads
);
deleteNETs
(
);
#if 0 && defined(DEBUG)
for( int p=0; p<pads.GetCount(); ++p )
pads[p]->Show( 0, std::cout );
#endif
}
// expand the net vector to highestNetCode+1, setting empty to NULL
nets
.
resize
(
highestNetCode
+
1
,
NULL
);
// skip netcode = 0
for
(
unsigned
i
=
1
;
i
<
nets
.
size
();
++
i
)
nets
[
i
]
=
new
NET
(
pcb
->
network
);
//-----<build the images and components>---------------------------------
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
);
}
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>------------------------------------------------
// 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
()
)
{
NETWORK
*
network
=
pcb
->
network
;
TYPE_COLLECTOR
nets
;
TYPE_COLLECTOR
pads
;
static
const
KICAD_T
scanNETs
[]
=
{
PCB_EQUIPOT_STRUCT_TYPE
,
EOT
};
PADSTACKSET
::
auto_type
ps
=
padstackset
.
release
(
i
);
PADSTACK
*
padstack
=
ps
.
release
();
nets
.
Collect
(
aBoard
,
scanNETs
);
items
.
Collect
(
aBoard
,
scanMODULEs
);
PIN_REF
emptypin
(
0
);
pcb
->
library
->
AddPadstack
(
padstack
);
}
for
(
int
n
=
0
;
n
<
nets
.
GetCount
();
++
n
)
// copy our SPECCTRA_DB::nets to the pcb->network
for
(
unsigned
n
=
1
;
n
<
nets
.
size
();
++
n
)
{
EQUIPOT
*
kinet
=
(
EQUIPOT
*
)
nets
[
n
];
if
(
kinet
->
GetNet
()
==
0
)
continue
;
NET
*
net
=
nets
[
n
];
if
(
net
->
pins
.
size
()
)
{
// give ownership to pcb->network
pcb
->
network
->
nets
.
push_back
(
net
);
nets
[
n
]
=
0
;
}
}
}
NET
*
net
=
new
NET
(
network
);
network
->
nets
.
push_back
(
net
);
net
->
net_id
=
CONV_TO_UTF8
(
kinet
->
m_Netname
);
net
->
net_number
=
kinet
->
GetNet
();
//-----< 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.
for
(
int
m
=
0
;
m
<
items
.
GetCount
();
++
m
)
int
defaultViaSize
=
aBoard
->
m_BoardSettings
->
m_CurrentViaSize
;
if
(
defaultViaSize
)
{
MODULE
*
module
=
(
MODULE
*
)
items
[
m
];
PADSTACK
*
padstack
=
makeVia
(
defaultViaSize
,
g_DesignSettings
.
m_ViaDrill
,
0
,
aBoard
->
GetCopperLayerCount
()
-
1
);
pcb
->
library
->
AddPadstack
(
padstack
);
pads
.
Collect
(
module
,
scanPADs
);
// 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
p
=
0
;
p
<
pads
.
GetCount
();
++
p
)
for
(
int
i
=
0
;
i
<
HISTORY_NUMBER
;
++
i
)
{
D_PAD
*
pad
=
(
D_PAD
*
)
pads
[
p
];
int
viaSize
=
aBoard
->
m_BoardSettings
->
m_ViaSizeHistory
[
i
];
if
(
!
viaSize
)
break
;
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
();
if
(
viaSize
==
defaultViaSize
)
continue
;
pin_ref
->
SetParent
(
net
);
pin_ref
->
component_id
=
CONV_TO_UTF8
(
module
->
GetReference
()
);
pin_ref
->
pin_id
=
CONV_TO_UTF8
(
pad
->
ReturnStringPadName
()
);
}
}
}
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>-----------------------------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment