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
67ebe29b
Commit
67ebe29b
authored
Jan 29, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more free specctra work
parent
7878ba27
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
543 additions
and
170 deletions
+543
-170
change_log.txt
change_log.txt
+0
-2
specctra.cpp
pcbnew/specctra.cpp
+146
-14
specctra.h
pcbnew/specctra.h
+303
-95
specctra_export.cpp
pcbnew/specctra_export.cpp
+94
-59
No files found.
change_log.txt
View file @
67ebe29b
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:
...
...
pcbnew/specctra.cpp
View file @
67ebe29b
...
...
@@ -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
)
...
...
pcbnew/specctra.h
View file @
67ebe29b
...
...
@@ -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
)
void
SetShape
(
ELEM
*
aShape
)
{
// these are mutually exclusive
if
(
rectangle
)
rectangle
->
Format
(
out
,
nestLevel
);
else
if
(
path
)
path
->
Format
(
out
,
nestLevel
);
delete
shape
;
shape
=
aShape
;
else
if
(
circle
)
circle
->
Format
(
out
,
nestLevel
);
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
);
}
}
else
if
(
qarc
)
qarc
->
Format
(
out
,
nestLevel
);
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
;
...
...
pcbnew/specctra_export.cpp
View file @
67ebe29b
...
...
@@ -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.
p
ad
->
m_logical_connexion
=
padstackNdx
++
;
PADSTACK
*
padstack
=
new
PADSTACK
(
aLibrary
);
aLibrary
->
AddPadstack
(
padstack
)
;
PADSTACK
*
padstack
=
new
PADSTACK
(
pcb
->
library
);
p
cb
->
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,54 +791,60 @@ 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.
...
...
@@ -822,6 +856,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
module
->
flag
=
0
;
}
}
}
...
...
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