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
501fb2c2
Commit
501fb2c2
authored
Jan 25, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more free specctra work
parent
22affc67
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
401 additions
and
177 deletions
+401
-177
change_log.txt
change_log.txt
+8
-0
specctra.cpp
pcbnew/specctra.cpp
+9
-17
specctra.h
pcbnew/specctra.h
+139
-34
specctra_export.cpp
pcbnew/specctra_export.cpp
+245
-126
No files found.
change_log.txt
View file @
501fb2c2
...
@@ -5,6 +5,14 @@ Please add newer entries at the top, list the date and your name with
...
@@ -5,6 +5,14 @@ Please add newer entries at the top, list the date and your name with
email address.
email address.
2008-Jan-25 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew:
SPECCTRA export does padstacks ok, except that oval arcs need to be split
into quarter circle arcs, and no consideration is given to "layer types"
See page bottom of page 74 of the SECCTRA Design Language Reference, May 2000.
Still working today...
2008-Jan-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
2008-Jan-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
================================================================================
...
...
pcbnew/specctra.cpp
View file @
501fb2c2
...
@@ -1985,7 +1985,7 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
...
@@ -1985,7 +1985,7 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
case
T_polygon
:
case
T_polygon
:
case
T_qarc
:
case
T_qarc
:
L_done_that
:
L_done_that
:
if
(
growth
->
Length
()
)
if
(
growth
->
shape
)
unexpected
(
tok
);
unexpected
(
tok
);
break
;
break
;
default
:
default
:
...
@@ -2000,32 +2000,24 @@ L_done_that:
...
@@ -2000,32 +2000,24 @@ L_done_that:
switch
(
tok
)
switch
(
tok
)
{
{
case
T_rect
:
case
T_rect
:
RECTANGLE
*
rectangle
;
growth
->
shape
=
new
RECTANGLE
(
growth
);
rectangle
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
(
RECTANGLE
*
)
growth
->
shape
);
growth
->
Append
(
rectangle
);
doRECTANGLE
(
rectangle
);
break
;
break
;
case
T_circle
:
case
T_circle
:
CIRCLE
*
circle
;
growth
->
shape
=
new
CIRCLE
(
growth
);
circle
=
new
CIRCLE
(
growth
);
doCIRCLE
(
(
CIRCLE
*
)
growth
->
shape
);
growth
->
Append
(
circle
);
doCIRCLE
(
circle
);
break
;
break
;
case
T_path
:
case
T_path
:
case
T_polygon
:
case
T_polygon
:
PATH
*
path
;
growth
->
shape
=
new
PATH
(
growth
,
tok
);
path
=
new
PATH
(
growth
,
tok
);
doPATH
(
(
PATH
*
)
growth
->
shape
);
growth
->
Append
(
path
);
doPATH
(
path
);
break
;
break
;
case
T_qarc
:
case
T_qarc
:
QARC
*
qarc
;
growth
->
shape
=
new
QARC
(
growth
);
qarc
=
new
QARC
(
growth
);
doQARC
(
(
QARC
*
)
growth
->
shape
);
growth
->
Append
(
qarc
);
doQARC
(
qarc
);
break
;
break
;
case
T_connect
:
case
T_connect
:
...
...
pcbnew/specctra.h
View file @
501fb2c2
...
@@ -126,6 +126,25 @@ struct POINT
...
@@ -126,6 +126,25 @@ struct POINT
return
!
(
*
this
==
other
);
return
!
(
*
this
==
other
);
}
}
POINT
&
operator
+=
(
const
POINT
&
other
)
{
x
+=
other
.
x
;
y
+=
other
.
y
;
return
*
this
;
}
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 Format
* Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
...
@@ -425,13 +444,16 @@ public:
...
@@ -425,13 +444,16 @@ public:
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
{
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
)
;
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g %.6g %.6g %.6g)
\n
"
,
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g %.6g %.6g %.6g)%s"
,
LEXER
::
GetTokenText
(
Type
()
),
LEXER
::
GetTokenText
(
Type
()
),
quote
,
layer_id
.
c_str
(),
quote
,
quote
,
layer_id
.
c_str
(),
quote
,
point0
.
x
,
point0
.
y
,
point0
.
x
,
point0
.
y
,
point1
.
x
,
point1
.
y
);
point1
.
x
,
point1
.
y
,
newline
);
}
}
};
};
...
@@ -587,12 +609,20 @@ public:
...
@@ -587,12 +609,20 @@ public:
aperture_type
=
T_round
;
aperture_type
=
T_round
;
}
}
~
PATH
(
)
void
AppendPoint
(
const
POINT
&
aPoint
)
{
{
points
.
push_back
(
aPoint
);
}
void
SetLayerId
(
const
char
*
aLayerId
)
{
layer_id
=
aLayerId
;
}
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
const
int
RIGHTMARGIN
=
80
;
const
int
RIGHTMARGIN
=
80
;
...
@@ -607,6 +637,7 @@ public:
...
@@ -607,6 +637,7 @@ public:
{
{
out
->
Print
(
0
,
"
\n
"
);
out
->
Print
(
0
,
"
\n
"
);
perLine
=
out
->
Print
(
nestLevel
+
1
,
"%s"
,
""
);
perLine
=
out
->
Print
(
nestLevel
+
1
,
"%s"
,
""
);
newline
=
"
\n
"
;
}
}
else
else
perLine
+=
out
->
Print
(
0
,
" "
);
perLine
+=
out
->
Print
(
0
,
" "
);
...
@@ -617,10 +648,10 @@ public:
...
@@ -617,10 +648,10 @@ public:
if
(
aperture_type
==
T_square
)
if
(
aperture_type
==
T_square
)
{
{
out
->
Print
(
0
,
"
\n
"
);
out
->
Print
(
0
,
"
\n
"
);
out
->
Print
(
nestLevel
+
1
,
"(aperture_type square)
\n
"
);
out
->
Print
(
nestLevel
+
1
,
"(aperture_type square)
)
\n
"
);
}
}
else
out
->
Print
(
0
,
")
\n
"
);
out
->
Print
(
0
,
")%s"
,
newline
);
}
}
};
};
typedef
boost
::
ptr_vector
<
PATH
>
PATHS
;
typedef
boost
::
ptr_vector
<
PATH
>
PATHS
;
...
@@ -672,7 +703,7 @@ class CIRCLE : public ELEM
...
@@ -672,7 +703,7 @@ class CIRCLE : public ELEM
std
::
string
layer_id
;
std
::
string
layer_id
;
double
diameter
;
double
diameter
;
POINT
vertex
;
POINT
vertex
;
// POINT's constructor sets to (0,0)
public
:
public
:
CIRCLE
(
ELEM
*
aParent
)
:
CIRCLE
(
ELEM
*
aParent
)
:
...
@@ -683,10 +714,17 @@ public:
...
@@ -683,10 +714,17 @@ public:
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g %.6g %.6g)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
,
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
layer_id
.
c_str
(),
quote
,
quote
,
layer_id
.
c_str
(),
quote
,
diameter
,
vertex
.
x
,
vertex
.
y
);
diameter
);
if
(
vertex
.
x
!=
0
.
0
||
vertex
.
y
!=
0
.
0
)
out
->
Print
(
0
,
" %.6g %.6g)%s"
,
vertex
.
x
,
vertex
.
y
,
newline
);
else
out
->
Print
(
0
,
")%s"
,
newline
);
}
}
void
SetLayerId
(
const
char
*
aLayerId
)
void
SetLayerId
(
const
char
*
aLayerId
)
...
@@ -698,6 +736,11 @@ public:
...
@@ -698,6 +736,11 @@ public:
{
{
diameter
=
aDiameter
;
diameter
=
aDiameter
;
}
}
void
SetVertex
(
const
POINT
&
aVertex
)
{
vertex
=
aVertex
;
}
};
};
...
@@ -718,15 +761,34 @@ public:
...
@@ -718,15 +761,34 @@ public:
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
,
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
)
,
quote
,
layer_id
.
c_str
(),
quote
,
quote
,
layer_id
.
c_str
(),
quote
,
aperture_width
);
aperture_width
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
for
(
int
i
=
0
;
i
<
3
;
++
i
)
out
->
Print
(
nestLevel
+
1
,
"%.6g %.6g
\n
"
,
vertex
[
i
].
x
,
vertex
[
i
].
y
);
out
->
Print
(
0
,
" %.6g %.6g
"
,
vertex
[
i
].
x
,
vertex
[
i
].
y
);
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
0
,
")%s"
,
newline
);
}
void
SetLayerId
(
const
char
*
aLayerId
)
{
layer_id
=
aLayerId
;
}
void
SetStart
(
const
POINT
&
aStart
)
{
vertex
[
0
]
=
aStart
;
}
void
SetEnd
(
const
POINT
&
aEnd
)
{
vertex
[
1
]
=
aEnd
;
}
void
SetCenter
(
const
POINT
&
aCenter
)
{
vertex
[
2
]
=
aCenter
;
}
}
};
};
...
@@ -1641,40 +1703,85 @@ public:
...
@@ -1641,40 +1703,85 @@ public:
};
};
class
SHAPE
:
public
ELEM_HOLDER
/**
* Class SHAPE
* corresponds to the "(shape ..)" element in the specctra dsn spec.
* It is not a <shape_descriptor> which is one of things that this
* elements contains, i.e. in its "shape" field. This class also implements
* the "(outline ...)" element as a dual personality.
*/
class
SHAPE
:
public
ELEM
{
{
friend
class
SPECCTRA_DB
;
friend
class
SPECCTRA_DB
;
DSN_T
connect
;
DSN_T
connect
;
/*
----- only one of these is used, like a union -----
/*
<shape_descriptor >::=
single item, but now in the kids list
[<rectangle_descriptor> |
<circle_descriptor> |
PATH* path; ///< used for both path and polygon
<polygon_descriptor> |
RECTANGLE* rectangle;
<path_descriptor> |
CIRCLE* circle;
<qarc_descriptor> ]
QARC* qarc;
*/
//--------------------------------------------------- */
ELEM
*
shape
;
WINDOWS
windows
;
WINDOWS
windows
;
public
:
public
:
SHAPE
(
ELEM
*
aParent
,
DSN_T
aType
=
T_shape
)
:
SHAPE
(
ELEM
*
aParent
,
DSN_T
aType
=
T_shape
)
:
ELEM
_HOLDER
(
aType
,
aParent
)
ELEM
(
aType
,
aParent
)
{
{
connect
=
T_on
;
connect
=
T_on
;
shape
=
0
;
}
~
SHAPE
()
{
delete
shape
;
}
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
void
SetShape
(
ELEM
*
aShape
)
{
{
ELEM_HOLDER
::
FormatContents
(
out
,
nestLevel
)
;
delete
shape
;
if
(
connect
==
T_off
)
shape
=
aShape
;
out
->
Print
(
nestLevel
,
"(connect %s)
\n
"
,
LEXER
::
GetTokenText
(
connect
)
);
for
(
WINDOWS
::
iterator
i
=
windows
.
begin
();
i
!=
windows
.
end
();
++
i
)
if
(
aShape
)
i
->
Format
(
out
,
nestLevel
);
{
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
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s "
,
LEXER
::
GetTokenText
(
Type
()
)
);
if
(
shape
)
shape
->
Format
(
out
,
0
);
if
(
connect
==
T_off
)
out
->
Print
(
0
,
"(connect %s)"
,
LEXER
::
GetTokenText
(
connect
)
);
if
(
windows
.
size
()
)
{
out
->
Print
(
0
,
"
\n
"
);
for
(
WINDOWS
::
iterator
i
=
windows
.
begin
();
i
!=
windows
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
else
out
->
Print
(
0
,
")
\n
"
);
}
}
};
};
...
@@ -3324,10 +3431,8 @@ public:
...
@@ -3324,10 +3431,8 @@ public:
* of class WinEDA_BasePcbFrame rather than class BOARD.
* of class WinEDA_BasePcbFrame rather than class BOARD.
*
*
* @param aBoard The BOARD to convert to a PCB.
* @param aBoard The BOARD to convert to a PCB.
* @throw IOError, if the BOARD cannot be converted, and the text of the
* exception tells the error message.
*/
*/
void
FromBOARD
(
BOARD
*
aBoard
)
throw
(
IOError
)
;
void
FromBOARD
(
BOARD
*
aBoard
);
/**
/**
...
...
pcbnew/specctra_export.cpp
View file @
501fb2c2
...
@@ -67,20 +67,6 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
...
@@ -67,20 +67,6 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
db
.
SetPCB
(
SPECCTRA_DB
::
MakePCB
()
);
db
.
SetPCB
(
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.
for
(
MODULE
*
module
=
m_Pcb
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
{
module
->
flag
=
0
;
if
(
module
->
GetLayer
()
==
COPPER_LAYER_N
)
{
m_Pcb
->
Change_Side_Module
(
module
,
NULL
);
module
->
flag
=
1
;
}
}
try
try
{
{
db
.
FromBOARD
(
m_Pcb
);
db
.
FromBOARD
(
m_Pcb
);
...
@@ -97,17 +83,6 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
...
@@ -97,17 +83,6 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
errorText
=
ioe
.
errorText
;
errorText
=
ioe
.
errorText
;
}
}
// DSN Images (=Kicad MODULES and pads) must be presented from the
// top view. Restore those that were flipped.
for
(
MODULE
*
module
=
m_Pcb
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
{
if
(
module
->
flag
)
{
m_Pcb
->
Change_Side_Module
(
module
,
NULL
);
module
->
flag
=
0
;
}
}
if
(
ok
)
if
(
ok
)
{
{
// @todo display a message saying the export is complete.
// @todo display a message saying the export is complete.
...
@@ -232,6 +207,34 @@ static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr )
...
@@ -232,6 +207,34 @@ static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr )
}
}
/**
* Function makePath
* creates a PATH element with a single straight line, a pair of vertices.
*/
static
PATH
*
makePath
(
const
POINT
&
aStart
,
const
POINT
&
aEnd
,
const
std
::
string
&
aLayerName
)
{
PATH
*
path
=
new
PATH
(
0
,
T_path
);
path
->
AppendPoint
(
aStart
);
path
->
AppendPoint
(
aEnd
);
path
->
SetLayerId
(
aLayerName
.
c_str
()
);
return
path
;
}
static
QARC
*
makeArc
(
const
POINT
&
aStart
,
const
POINT
&
aEnd
,
const
POINT
&
aCenter
,
const
std
::
string
&
aLayerName
)
{
QARC
*
qarc
=
new
QARC
(
0
);
qarc
->
SetStart
(
aStart
);
qarc
->
SetEnd
(
aEnd
);
qarc
->
SetCenter
(
aCenter
);
qarc
->
SetLayerId
(
aLayerName
.
c_str
()
);
return
qarc
;
}
/**
/**
* Function makePADSTACKs
* Function makePADSTACKs
* makes all the PADSTACKs, and marks each D_PAD with the index into the
* makes all the PADSTACKs, and marks each D_PAD with the index into the
...
@@ -247,7 +250,19 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
...
@@ -247,7 +250,19 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
D_PAD
*
old_pad
=
NULL
;
D_PAD
*
old_pad
=
NULL
;
int
padstackNdx
=
0
;
int
padstackNdx
=
0
;
// for now, report on only the top and bottom layers with respect to the copper
// within a 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.
std
::
string
layerId
[
2
]
=
{
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
LAYER_CMP_N
)),
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
COPPER_LAYER_N
)),
};
for
(
int
i
=
0
;
i
<
aPads
.
GetCount
();
++
i
)
for
(
int
i
=
0
;
i
<
aPads
.
GetCount
();
++
i
)
{
{
D_PAD
*
pad
=
(
D_PAD
*
)
aPads
[
i
];
D_PAD
*
pad
=
(
D_PAD
*
)
aPads
[
i
];
...
@@ -265,39 +280,51 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
...
@@ -265,39 +280,51 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
pad
->
m_logical_connexion
=
padstackNdx
++
;
pad
->
m_logical_connexion
=
padstackNdx
++
;
PADSTACK
*
padstack
=
new
PADSTACK
(
aLibrary
);
PADSTACK
*
padstack
=
new
PADSTACK
(
aLibrary
);
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
aLibrary
->
AddPadstack
(
padstack
);
padstack
->
Append
(
shape
);
// paddOfset is the offset of copper shape relative to hole position,
// and pad->m_Pos is hole position. All shapes must be shifted by
// this distance, normally (0,0).
// Note that the y correction here is set negative.
POINT
padOffset
(
scale
(
pad
->
m_Offset
.
x
),
-
scale
(
pad
->
m_Offset
.
y
)
);
bool
doLayer
[
2
]
=
{
pad
->
IsOnLayer
(
LAYER_CMP_N
),
pad
->
IsOnLayer
(
COPPER_LAYER_N
)
};
int
coppers
=
0
;
switch
(
pad
->
m_PadShape
)
switch
(
pad
->
m_PadShape
)
{
{
default:
default:
case
PAD_CIRCLE
:
case
PAD_CIRCLE
:
{
{
CIRCLE
*
circle
;
double
diameter
=
scale
(
pad
->
m_Size
.
x
);
double
diameter
=
scale
(
pad
->
m_Size
.
x
);
int
coppers
=
0
;
if
(
pad
->
IsOnLayer
(
COPPER_LAYER_N
)
)
{
circle
=
new
CIRCLE
(
shape
);
circle
->
SetLayerId
(
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
COPPER_LAYER_N
))
);
circle
->
SetDiameter
(
diameter
);
shape
->
Append
(
circle
);
++
coppers
;
}
if
(
pad
->
IsOnLayer
(
LAYER_CMP_N
)
)
for
(
int
layer
=
0
;
layer
<
2
;
++
layer
)
{
{
circle
=
new
CIRCLE
(
shape
);
if
(
doLayer
[
i
]
)
circle
->
SetLayerId
(
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
LAYER_CMP_N
))
);
{
circle
->
SetDiameter
(
diameter
);
CIRCLE
*
circle
;
shape
->
Append
(
circle
);
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
++
coppers
;
padstack
->
Append
(
shape
);
circle
=
new
CIRCLE
(
shape
);
shape
->
SetShape
(
circle
);
circle
->
SetLayerId
(
layerId
[
layer
].
c_str
()
);
circle
->
SetDiameter
(
diameter
);
circle
->
SetVertex
(
padOffset
);
++
coppers
;
}
}
}
char
name
[
50
];
snprintf
(
name
,
sizeof
(
name
),
"Round%dPad_%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
)
);
char
name
[
80
];
snprintf
(
name
,
sizeof
(
name
),
"Round%dPad_%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
)
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
name
[
sizeof
(
name
)
-
1
]
=
0
;
...
@@ -306,8 +333,6 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
...
@@ -306,8 +333,6 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
// name here. If so, blend in the padNdx into the name.
// name here. If so, blend in the padNdx into the name.
padstack
->
SetPadstackId
(
name
);
padstack
->
SetPadstackId
(
name
);
aLibrary
->
AddPadstack
(
padstack
);
}
}
break
;
break
;
...
@@ -315,29 +340,30 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
...
@@ -315,29 +340,30 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
{
{
double
dx
=
scale
(
pad
->
m_Size
.
x
)
/
2.0
;
double
dx
=
scale
(
pad
->
m_Size
.
x
)
/
2.0
;
double
dy
=
scale
(
pad
->
m_Size
.
y
)
/
2.0
;
double
dy
=
scale
(
pad
->
m_Size
.
y
)
/
2.0
;
POINT
lowerLeft
(
-
dx
,
-
dy
);
POINT
upperRight
(
dx
,
dy
);
RECTANGLE
*
rec
t
;
lowerLeft
+=
padOffse
t
;
int
coppers
=
0
;
upperRight
+=
padOffset
;
if
(
pad
->
IsOnLayer
(
COPPER_LAYER_N
)
)
for
(
int
layer
=
0
;
layer
<
2
;
++
layer
)
{
{
rect
=
new
RECTANGLE
(
shape
);
if
(
doLayer
[
i
]
)
rect
->
SetLayerId
(
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
COPPER_LAYER_N
))
);
{
rect
->
SetCorners
(
POINT
(
-
dx
,
-
dy
),
POINT
(
dx
,
dy
)
);
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
shape
->
Append
(
rect
);
padstack
->
Append
(
shape
);
++
coppers
;
RECTANGLE
*
rect
=
new
RECTANGLE
(
shape
);
shape
->
SetShape
(
rect
);
rect
->
SetLayerId
(
layerId
[
layer
].
c_str
()
);
rect
->
SetCorners
(
lowerLeft
,
upperRight
);
++
coppers
;
}
}
}
if
(
pad
->
IsOnLayer
(
LAYER_CMP_N
)
)
char
name
[
80
];
{
rect
=
new
RECTANGLE
(
shape
);
rect
->
SetLayerId
(
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
LAYER_CMP_N
))
);
rect
->
SetCorners
(
POINT
(
-
dx
,
-
dy
),
POINT
(
dx
,
dy
)
);
shape
->
Append
(
rect
);
++
coppers
;
}
char
name
[
50
];
snprintf
(
name
,
sizeof
(
name
),
"Rect%dPad_%.6gx%.6g_mil"
,
snprintf
(
name
,
sizeof
(
name
),
"Rect%dPad_%.6gx%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
),
scale
(
pad
->
m_Size
.
y
)
);
coppers
,
scale
(
pad
->
m_Size
.
x
),
scale
(
pad
->
m_Size
.
y
)
);
...
@@ -345,79 +371,145 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
...
@@ -345,79 +371,145 @@ static void makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads,
name
[
sizeof
(
name
)
-
1
]
=
0
;
name
[
sizeof
(
name
)
-
1
]
=
0
;
// @todo verify that all pad names are unique, there is a chance that
// @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
// D_PAD::Compare() could say two pads are different, yet the
y
get the same
// name here. If so, blend in the padNdx into the name.
// name here. If so, blend in the padNdx into the name.
padstack
->
SetPadstackId
(
name
);
padstack
->
SetPadstackId
(
name
);
aLibrary
->
AddPadstack
(
padstack
);
}
}
break
;
break
;
#if 0
pad_type = "RECTANGULAR";
case
PAD_OVAL
:
fprintf( file, " %s %d\n", pad_type, pad->m_Drill.x );
fprintf( file, "RECTANGLE %d %d %d %d\n",
-dx + pad->m_Offset.x, -dy - pad->m_Offset.y,
dx + pad->m_Offset.x, -pad->m_Offset.y + dy );
break;
case PAD_OVAL: /* description du contour par 2 linges et 2 arcs */
{
pad_type = "FINGER";
fprintf( file, " %s %d\n", pad_type, pad->m_Drill.x );
int dr = dx - dy;
if( dr >= 0 ) // ovale horizontal
{
{
int rayon = dy;
double
dx
=
scale
(
pad
->
m_Size
.
x
)
/
2.0
;
fprintf( file, "LINE %d %d %d %d\n",
double
dy
=
scale
(
pad
->
m_Size
.
y
)
/
2.0
;
-dr + pad->m_Offset.x, -pad->m_Offset.y - rayon,
double
dr
=
dx
-
dy
;
dr + pad->m_Offset.x, -pad->m_Offset.y - rayon );
fprintf( file, "ARC %d %d %d %d %d %d\n",
if
(
dr
>=
0
)
// oval is horizontal
dr + pad->m_Offset.x, -pad->m_Offset.y - rayon,
{
dr + pad->m_Offset.x, -pad->m_Offset.y + rayon,
double
radius
=
dy
;
dr + pad->m_Offset.x, -pad->m_Offset.y );
for
(
int
layer
=
0
;
layer
<
2
;
++
layer
)
{
// each oval is 2 lines and 4 (quarter circle) qarcs
fprintf( file, "LINE %d %d %d %d\n",
SHAPE
*
shape
;
dr + pad->m_Offset.x, -pad->m_Offset.y + rayon,
PATH
*
path
;
-dr + pad->m_Offset.x, -pad->m_Offset.y + rayon );
QARC
*
qarc
;
fprintf( file, "ARC %d %d %d %d %d %d\n",
-dr + pad->m_Offset.x, -pad->m_Offset.y + rayon,
shape
=
new
SHAPE
(
padstack
);
-dr + pad->m_Offset.x, -pad->m_Offset.y - rayon,
padstack
->
Append
(
shape
);
-dr + pad->m_Offset.x, -pad->m_Offset.y );
path
=
makePath
(
}
POINT
(
-
dr
+
padOffset
.
x
,
padOffset
.
y
-
radius
),
// aStart
else // ovale vertical
POINT
(
dr
+
padOffset
.
x
,
padOffset
.
y
-
radius
),
// aEnd
{
layerId
[
layer
]
);
dr = -dr;
shape
->
SetShape
(
path
);
int rayon = dx;
fprintf( file, "LINE %d %d %d %d\n",
shape
=
new
SHAPE
(
padstack
);
-rayon + pad->m_Offset.x, -pad->m_Offset.y - dr,
padstack
->
Append
(
shape
);
-rayon + pad->m_Offset.x, -pad->m_Offset.y + dr );
// @todo: this 1/2 circle arc needs to be split into two quarter circle arcs
fprintf( file, "ARC %d %d %d %d %d %d\n",
qarc
=
makeArc
(
-rayon + pad->m_Offset.x, -pad->m_Offset.y + dr,
POINT
(
dr
+
padOffset
.
x
,
padOffset
.
y
-
radius
),
// aStart
rayon + pad->m_Offset.x, -pad->m_Offset.y + dr,
POINT
(
dr
+
padOffset
.
x
,
padOffset
.
y
+
radius
),
// aEnd
pad->m_Offset.x, -pad->m_Offset.y + dr );
POINT
(
dr
+
padOffset
.
x
,
padOffset
.
y
),
// aCenter
layerId
[
layer
]
);
shape
->
SetShape
(
qarc
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
path
=
makePath
(
POINT
(
dr
+
padOffset
.
x
,
padOffset
.
y
+
radius
),
// aStart
POINT
(
-
dr
+
padOffset
.
x
,
padOffset
.
y
+
radius
),
// aEnd
layerId
[
layer
]
);
shape
->
SetShape
(
path
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
// @todo: this 1/2 circle arc needs to be split into two quarter circle arcs
qarc
=
makeArc
(
POINT
(
-
dr
+
padOffset
.
x
,
padOffset
.
y
+
radius
),
// aStart
POINT
(
-
dr
+
padOffset
.
x
,
padOffset
.
y
-
radius
),
// aEnd
POINT
(
-
dr
+
padOffset
.
x
,
padOffset
.
y
),
// aCenter
layerId
[
layer
]
);
shape
->
SetShape
(
qarc
);
}
}
else
// oval is vertical
{
double
radius
=
dx
;
dr
=
-
dr
;
for
(
int
layer
=
0
;
layer
<
2
;
++
layer
)
{
// each oval is 2 lines and 2 qarcs
fprintf( file, "LINE %d %d %d %d\n",
SHAPE
*
shape
;
rayon + pad->m_Offset.x, -pad->m_Offset.y + dr,
PATH
*
path
;
rayon + pad->m_Offset.x, -pad->m_Offset.y - dr );
QARC
*
qarc
;
fprintf( file, "ARC %d %d %d %d %d %d\n",
rayon + pad->m_Offset.x, -pad->m_Offset.y - dr,
shape
=
new
SHAPE
(
padstack
);
-rayon + pad->m_Offset.x, -pad->m_Offset.y - dr,
padstack
->
Append
(
shape
);
pad->m_Offset.x, -pad->m_Offset.y - dr );
path
=
makePath
(
POINT
(
-
radius
+
padOffset
.
x
,
padOffset
.
y
-
dr
),
// aStart
POINT
(
-
radius
+
padOffset
.
x
,
padOffset
.
y
+
dr
),
// aEnd
layerId
[
layer
]
);
shape
->
SetShape
(
path
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
// @todo: this 1/2 circle arc needs to be split into two quarter circle arcs
qarc
=
makeArc
(
POINT
(
-
radius
+
padOffset
.
x
,
padOffset
.
y
+
dr
),
// aStart
POINT
(
radius
+
padOffset
.
x
,
padOffset
.
y
+
dr
),
// aEnd
POINT
(
padOffset
.
x
,
padOffset
.
y
+
dr
),
// aCenter
layerId
[
layer
]
);
shape
->
SetShape
(
qarc
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
path
=
makePath
(
POINT
(
radius
+
padOffset
.
x
,
padOffset
.
y
+
dr
),
// aStart
POINT
(
radius
+
padOffset
.
x
,
padOffset
.
y
-
dr
),
// aEnd
layerId
[
layer
]
);
shape
->
SetShape
(
path
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
// @todo: this 1/2 circle arc needs to be split into two quarter circle arcs
qarc
=
makeArc
(
POINT
(
radius
+
padOffset
.
x
,
padOffset
.
y
-
dr
),
// aStart
POINT
(
-
radius
+
padOffset
.
x
,
padOffset
.
y
-
dr
),
// aEnd
POINT
(
padOffset
.
x
,
padOffset
.
y
-
dr
),
// aCenter
layerId
[
layer
]
);
shape
->
SetShape
(
qarc
);
}
}
char
name
[
80
];
snprintf
(
name
,
sizeof
(
name
),
"Oval%dPad_%.6gx%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
),
scale
(
pad
->
m_Size
.
y
)
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
// @todo verify that all pad names are unique, there is a chance that
// D_PAD::Compare() could say two pads are different, yet they get the same
// name here. If so, blend in the padNdx into the name.
padstack
->
SetPadstackId
(
name
);
}
}
break
;
break
;
}
/*
case PAD_TRAPEZOID:
case PAD_TRAPEZOID:
pad_type = "POLYGON";
break;
break;
#endif
*/
}
}
}
}
}
}
void
SPECCTRA_DB
::
FromBOARD
(
BOARD
*
aBoard
)
throw
(
IOError
)
void
SPECCTRA_DB
::
FromBOARD
(
BOARD
*
aBoard
)
{
{
TYPE_COLLECTOR
items
;
TYPE_COLLECTOR
items
;
POINT_PAIRS
ppairs
;
POINT_PAIRS
ppairs
;
...
@@ -426,6 +518,21 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
...
@@ -426,6 +518,21 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
if
(
!
pcb
)
if
(
!
pcb
)
pcb
=
SPECCTRA_DB
::
MakePCB
();
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.
for
(
MODULE
*
module
=
aBoard
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
{
module
->
flag
=
0
;
if
(
module
->
GetLayer
()
==
COPPER_LAYER_N
)
{
aBoard
->
Change_Side_Module
(
module
,
NULL
);
module
->
flag
=
1
;
}
}
//-----<unit_descriptor> & <resolution_descriptor>--------------------
//-----<unit_descriptor> & <resolution_descriptor>--------------------
{
{
pcb
->
unit
->
units
=
T_mil
;
pcb
->
unit
->
units
=
T_mil
;
...
@@ -463,7 +570,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
...
@@ -463,7 +570,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
{
{
swapEnds
(
ppairs
);
swapEnds
(
ppairs
);
#if defined(DEBUG)
#if
0 &&
defined(DEBUG)
for( unsigned i=0; i<ppairs.size(); ++i )
for( unsigned i=0; i<ppairs.size(); ++i )
{
{
POINT_PAIR* p = &ppairs[i];
POINT_PAIR* p = &ppairs[i];
...
@@ -539,7 +646,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
...
@@ -539,7 +646,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
layer
->
name
=
CONV_TO_UTF8
(
layerName
);
layer
->
name
=
CONV_TO_UTF8
(
layerName
);
// layer->type =
// layer->type = @todo need this, the export would be better.
pcb
->
structure
->
layers
.
push_back
(
layer
);
pcb
->
structure
->
layers
.
push_back
(
layer
);
}
}
}
}
...
@@ -589,9 +697,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
...
@@ -589,9 +697,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
// get all the D_PADs into pads.
// get all the D_PADs into pads.
pads
.
Collect
(
aBoard
,
scanPADs
);
pads
.
Collect
(
aBoard
,
scanPADs
);
makePADSTACKs
(
aBoard
,
pads
,
pcb
->
library
,
pcb
->
library
->
padstacks
);
makePADSTACKs
(
aBoard
,
pads
,
pcb
->
library
,
pcb
->
library
->
padstacks
);
#if defined(DEBUG)
#if
0 &&
defined(DEBUG)
for( int p=0; p<pads.GetCount(); ++p )
for( int p=0; p<pads.GetCount(); ++p )
pads[p]->Show( 0, std::cout );
pads[p]->Show( 0, std::cout );
#endif
#endif
...
@@ -626,6 +735,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
...
@@ -626,6 +735,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
}
}
// 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
()
)
{
if
(
module
->
flag
)
{
aBoard
->
Change_Side_Module
(
module
,
NULL
);
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