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
b9f9d539
Commit
b9f9d539
authored
Feb 01, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more amazing free specctra software
parent
4a0b5607
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
182 additions
and
70 deletions
+182
-70
change_log.txt
change_log.txt
+15
-0
specctra.cpp
pcbnew/specctra.cpp
+1
-1
specctra.h
pcbnew/specctra.h
+6
-7
specctra_export.cpp
pcbnew/specctra_export.cpp
+160
-62
No files found.
change_log.txt
View file @
b9f9d539
...
...
@@ -5,6 +5,21 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-Jan-29 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew:
SPECCTRA export now exports pads with offset OK, exports oval pads OK,
and tries to do less with pcb edges that are not a connected set of lines,
putting the burden back on the PCBNEW user to have clean perimeter lines.
Discovered that freerouter does not support oval pads yet, asked
for enhancement. Discovered a small problem if you modify a PAD in
the MODULE editor but do not replicate that change throughout all module
instances in the board. Is on my @todo list. Otherwise it is getting pretty
good now. Most boards load into freerouter, except mine, which if exported
with part numbers, hangs the freerouter! I may be away for a few days doing
billable work, after which I will begin the 2 imports, *.dsn and *.ses.
2008-Jan-31 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
...
...
pcbnew/specctra.cpp
View file @
b9f9d539
...
...
@@ -42,7 +42,7 @@
Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
If the contained object is small, then std::vector tends to be used.
If the contained object is large, variable size, or would require writing
an assignment operator() or copy constructor
e
, then boost::ptr_vector
an assignment operator() or copy constructor, then boost::ptr_vector
cannot be beat.
*/
...
...
pcbnew/specctra.h
View file @
b9f9d539
...
...
@@ -695,19 +695,19 @@ public:
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
const
int
RIGHTMARGIN
=
8
0
;
const
int
RIGHTMARGIN
=
7
0
;
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
layer_id
.
c_str
(),
quote
,
aperture_width
);
int
wrapNest
=
MAX
(
nestLevel
+
1
,
6
);
for
(
unsigned
i
=
0
;
i
<
points
.
size
();
++
i
)
{
if
(
perLine
>
RIGHTMARGIN
)
{
out
->
Print
(
0
,
"
\n
"
);
perLine
=
out
->
Print
(
nestLevel
+
1
,
"%s"
,
""
);
newline
=
"
\n
"
;
perLine
=
out
->
Print
(
wrapNest
,
"%s"
,
""
);
}
else
perLine
+=
out
->
Print
(
0
,
" "
);
...
...
@@ -717,10 +717,9 @@ public:
if
(
aperture_type
==
T_square
)
{
out
->
Print
(
0
,
"
\n
"
);
out
->
Print
(
nestLevel
+
1
,
"(aperture_type square))
\n
"
);
out
->
Print
(
0
,
"(aperture_type square)"
);
}
else
out
->
Print
(
0
,
")%s"
,
newline
);
}
};
...
...
pcbnew/specctra_export.cpp
View file @
b9f9d539
...
...
@@ -74,6 +74,9 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
bool
ok
=
true
;
wxString
errorText
;
BASE_SCREEN
*
screen
=
GetScreen
();
bool
wasModified
=
screen
->
IsModify
()
&&
!
screen
->
IsSave
();
db
.
SetPCB
(
SPECCTRA_DB
::
MakePCB
()
);
try
...
...
@@ -92,6 +95,12 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
errorText
=
ioe
.
errorText
;
}
// The two calls below to BOARD::Change_Side_Module(), both set the
// modified flag, yet their actions cancel each other out, so it should
// be ok to clear the modify flag.
if
(
!
wasModified
)
screen
->
ClrModify
();
if
(
ok
)
{
// @todo display a message saying the export is complete.
...
...
@@ -105,8 +114,8 @@ namespace DSN {
struct
POINT_PAIR
{
POINT
p1
;
///< start
POINT
p2
;
///< end
POINT
start
;
POINT
end
;
BOARD_ITEM
*
item
;
///< the item which has these points, TRACK or DRAWSEGMENT
};
typedef
std
::
vector
<
POINT_PAIR
>
POINT_PAIRS
;
...
...
@@ -114,9 +123,9 @@ typedef std::vector<POINT_PAIR> POINT_PAIRS;
static
inline
void
swap
(
POINT_PAIR
&
pair
)
{
POINT
temp
=
pair
.
p1
;
pair
.
p1
=
pair
.
p2
;
pair
.
p2
=
temp
;
POINT
temp
=
pair
.
start
;
pair
.
start
=
pair
.
end
;
pair
.
end
=
temp
;
}
...
...
@@ -157,6 +166,31 @@ static POINT mapPt( const wxPoint& pt )
}
/**
* Function findPOINT
* searches the list of POINT_PAIRS for a matching end to the given POINT.
* @return int - 0 if no match, or + one based index of a POINT_PAIR with a matching ".start",
* or a - one based index of a POINT_PAIR with a matching ".end".
*/
static
int
findPOINT
(
const
POINT
&
pt
,
const
POINT_PAIR
source
[],
int
count
)
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
pt
==
source
[
i
].
start
)
{
return
+
(
i
+
1
);
}
if
(
pt
==
source
[
i
].
end
)
{
return
-
(
i
+
1
);
}
}
return
0
;
}
/**
* Function swapEnds
* will swap ends of any POINT_PAIR in the POINT_PAIRS list in order to
...
...
@@ -164,23 +198,46 @@ static POINT mapPt( const wxPoint& pt )
*/
static
void
swapEnds
(
POINT_PAIRS
&
aList
)
{
POINT
temp
;
if
(
aList
.
size
()
<=
1
)
if
(
!
aList
.
size
()
)
return
;
for
(
unsigned
i
=
0
;
i
<
aList
.
size
();
++
i
)
// do an extraction sort based on matching ends here.
POINT_PAIRS
sorted
;
POINT_PAIRS
source
(
aList
);
// try and start the search using a POINT which has at least one match elsewhere.
if
(
findPOINT
(
source
.
begin
()
->
start
,
&
source
[
1
],
source
.
size
()
-
1
)
!=
0
)
swap
(
*
source
.
begin
()
);
// swap start and end of first PAIR
while
(
source
.
size
()
)
{
if
(
aList
[
i
].
p1
==
aList
[
i
+
1
].
p1
)
swap
(
aList
[
i
]
);
sorted
.
push_back
(
*
source
.
begin
()
);
source
.
erase
(
source
.
begin
()
);
else
if
(
aList
[
i
].
p1
==
aList
[
i
+
1
].
p2
)
// keep looping through the source list looking for a match to the end of the last sorted.
int
result
;
while
(
(
result
=
findPOINT
(
sorted
.
back
().
end
,
&
source
[
0
],
source
.
size
()
)
)
!=
0
)
{
swap
(
aList
[
i
]
);
swap
(
aList
[
i
+
1
]
);
++
i
;
// skip next one, we swapped i+1 here
int
ndx
=
ABS
(
result
)
-
1
;
sorted
.
push_back
(
source
[
ndx
]
);
source
.
erase
(
source
.
begin
()
+
ndx
);
if
(
result
<
0
)
swap
(
sorted
.
back
()
);
}
}
#if 1 && defined(DEBUG)
printf
(
"swapEnds():
\n
"
);
for
(
unsigned
i
=
0
;
i
<
sorted
.
size
();
++
i
)
{
printf
(
"(%.6g,%.6g) (%.6g,%.6g)
\n
"
,
sorted
[
i
].
start
.
x
,
sorted
[
i
].
start
.
y
,
sorted
[
i
].
end
.
x
,
sorted
[
i
].
end
.
y
);
}
#endif
aList
=
sorted
;
}
...
...
@@ -197,15 +254,15 @@ static bool isRectangle( POINT_PAIRS& aList )
for
(
unsigned
i
=
0
;
i
<
aList
.
size
();
++
i
)
{
if
(
i
<
aList
.
size
()
-
1
)
if
(
aList
[
i
].
p2
!=
aList
[
i
+
1
].
p1
)
if
(
aList
[
i
].
end
!=
aList
[
i
+
1
].
start
)
return
false
;
if
(
aList
[
i
].
p1
.
x
!=
aList
[
i
].
p2
.
x
&&
aList
[
i
].
p1
.
y
!=
aList
[
i
].
p2
.
y
)
if
(
aList
[
i
].
start
.
x
!=
aList
[
i
].
end
.
x
&&
aList
[
i
].
start
.
y
!=
aList
[
i
].
end
.
y
)
return
false
;
}
return
(
aList
[
0
].
p1
==
aList
[
3
].
p2
);
return
(
aList
[
0
].
start
==
aList
[
3
].
end
);
}
return
false
;
}
...
...
@@ -316,7 +373,11 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
pin
->
padstack_id
=
padstack
->
padstack_id
;
pin
->
pin_id
=
CONV_TO_UTF8
(
pad
->
ReturnStringPadName
()
);
pin
->
SetVertex
(
mapPt
(
pad
->
m_Pos0
)
);
// copper shape's position is hole position + offset
wxPoint
pos
=
pad
->
m_Pos0
+
pad
->
m_Offset
;
pin
->
SetVertex
(
mapPt
(
pos
)
);
}
}
...
...
@@ -421,14 +482,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
// 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
// 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
)
);
// For now, we will report only one layer for the pads. SMD pads are reported on the
// top layer, and through hole are reported on <reserved_layer_name> "signal".
// We could do better if there was actually a "layer type" field within
...
...
@@ -462,7 +515,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
circle
->
SetLayerId
(
layerName
);
circle
->
SetDiameter
(
diameter
);
circle
->
SetVertex
(
padOffset
);
++
coppers
;
}
}
...
...
@@ -486,9 +538,6 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
POINT
lowerLeft
(
-
dx
,
-
dy
);
POINT
upperRight
(
dx
,
dy
);
lowerLeft
+=
padOffset
;
upperRight
+=
padOffset
;
for
(
int
layer
=
0
;
layer
<
reportedLayers
;
++
layer
)
{
if
(
doLayer
[
layer
]
)
...
...
@@ -540,38 +589,55 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
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
POINT
(
-
dr
,
-
radius
),
// aStart
POINT
(
dr
,
-
radius
),
// aEnd
layerName
);
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
POINT
(
dr
,
-
radius
),
// aStart
POINT
(
dr
,
0.0
),
// aEnd
POINT
(
dr
,
0.0
),
// aCenter
layerName
);
shape
->
SetShape
(
qarc
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
qarc
=
makeArc
(
POINT
(
dr
,
0.0
),
// aStart
POINT
(
dr
,
radius
),
// aEnd
POINT
(
dr
,
0.0
),
// aCenter
layerName
);
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
POINT
(
dr
,
radius
),
// aStart
POINT
(
-
dr
,
radius
),
// aEnd
layerName
);
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
POINT
(
-
dr
,
radius
),
// aStart
POINT
(
-
dr
,
0.0
),
// aEnd
POINT
(
-
dr
,
0.0
),
// aCenter
layerName
);
shape
->
SetShape
(
qarc
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
qarc
=
makeArc
(
POINT
(
-
dr
,
0.0
),
// aStart
POINT
(
-
dr
,
-
radius
),
// aEnd
POINT
(
-
dr
,
0.0
),
// aCenter
layerName
);
shape
->
SetShape
(
qarc
);
++
coppers
;
}
}
...
...
@@ -595,38 +661,55 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
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
POINT
(
-
radius
,
-
dr
),
// aStart
POINT
(
-
radius
,
dr
),
// aEnd
layerName
);
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
POINT
(
-
radius
,
dr
),
// aStart
POINT
(
0.0
,
dy
),
// aEnd
POINT
(
0.0
,
dr
),
// aCenter
layerName
);
shape
->
SetShape
(
qarc
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
qarc
=
makeArc
(
POINT
(
0.0
,
dy
),
// aStart
POINT
(
radius
,
dr
),
// aEnd
POINT
(
0.0
,
dr
),
// aCenter
layerName
);
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
POINT
(
radius
,
dr
),
// aStart
POINT
(
radius
,
-
dr
),
// aEnd
layerName
);
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
POINT
(
radius
,
-
dr
),
// aStart
POINT
(
0.0
,
-
dy
),
// aEnd
POINT
(
0.0
,
-
dr
),
// aCenter
layerName
);
shape
->
SetShape
(
qarc
);
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
qarc
=
makeArc
(
POINT
(
0.0
,
-
dy
),
// aStart
POINT
(
-
radius
,
-
dr
),
// aEnd
POINT
(
0.0
,
-
dr
),
// aCenter
layerName
);
shape
->
SetShape
(
qarc
);
++
coppers
;
}
}
...
...
@@ -774,8 +857,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
if
(
item
->
GetLayer
()
==
EDGE_N
)
{
pair
.
p1
=
mapPt
(
item
->
m_Start
);
pair
.
p2
=
mapPt
(
item
->
m_End
);
pair
.
start
=
mapPt
(
item
->
m_Start
);
pair
.
end
=
mapPt
(
item
->
m_End
);
pair
.
item
=
item
;
ppairs
.
push_back
(
pair
);
haveEdges
=
true
;
...
...
@@ -802,12 +885,14 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
rect
->
layer_id
=
"pcb"
;
// opposite corners
rect
->
SetCorners
(
ppairs
[
0
].
p1
,
ppairs
[
2
].
p1
);
rect
->
SetCorners
(
ppairs
[
0
].
start
,
ppairs
[
2
].
start
);
boundary
->
rectangle
=
rect
;
}
else
{
#if 0 // PCBNEW user's edges are rarely this clean, let the router figure
// out the mess by using code at #else below.
PATH* path = new PATH( boundary );
path->layer_id = "pcb";
...
...
@@ -815,10 +900,21 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
{
// unless its a closed polygon, this probably won't work,
// otherwise it will.
path
->
points
.
push_back
(
ppairs
[
i
].
p1
);
path->points.push_back( ppairs[i].
start
);
}
boundary->paths.push_back( path );
#else
for
(
unsigned
i
=
0
;
i
<
ppairs
.
size
();
++
i
)
{
PATH
*
path
=
new
PATH
(
boundary
);
boundary
->
paths
.
push_back
(
path
);
path
->
layer_id
=
"pcb"
;
path
->
points
.
push_back
(
ppairs
[
i
].
start
);
path
->
points
.
push_back
(
ppairs
[
i
].
end
);
}
#endif
}
pcb
->
structure
->
SetBOUNDARY
(
boundary
);
...
...
@@ -960,6 +1056,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
delete
image
;
}
// @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
->
image_id
);
PLACE
*
place
=
new
PLACE
(
comp
);
...
...
@@ -968,8 +1068,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
place
->
SetRotation
(
module
->
m_Orient
/
10.0
);
place
->
SetVertex
(
mapPt
(
module
->
m_Pos
)
);
place
->
component_id
=
CONV_TO_UTF8
(
module
->
GetReference
()
);
// not supported by freerouting.net yet:
place
->
part_number
=
CONV_TO_UTF8
(
module
->
GetValue
()
);
// module is flipped from bottom side, set side to T_back
...
...
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