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
a91eabb8
Commit
a91eabb8
authored
Jun 16, 2014
by
unknown
Committed by
jean-pierre charras
Jun 16, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply vrml_layer_pth, from Cirilo Bernardo
parent
52d2e7eb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
394 additions
and
153 deletions
+394
-153
export_vrml.cpp
pcbnew/exporters/export_vrml.cpp
+70
-72
vrml_layer.cpp
utils/idftools/vrml_layer.cpp
+284
-70
vrml_layer.h
utils/idftools/vrml_layer.h
+40
-11
No files found.
pcbnew/exporters/export_vrml.cpp
View file @
a91eabb8
...
@@ -25,37 +25,6 @@
...
@@ -25,37 +25,6 @@
*/
*/
/*
* NOTE:
* 1. for improved looks, create a DRILL layer for PTH drills.
* To render the improved board, render the vertical outline only
* for the board (no added drill holes), then render the
* outline only for PTH, and finally render the top and bottom
* of the board. NOTE: if we don't want extra eye-candy then
* we must maintain the current board export.
* Additional bits needed for improved eyecandy:
* + CalcOutline: calculates only the outline of a VRML_LAYER or
* a VERTICAL_HOLES
* + WriteVerticalIndices: writes the indices of only the vertical
* facets of a VRML_LAYER or a VRML_HOLES.
* + WriteVerticalVertices: writes only the outline vertices to
* form vertical walls; applies to VRML_LAYER and VRML_HOLES
*
* 2. How can we suppress fiducials such as those in the corners of the pic-programmer demo?
*
*/
/*
* KNOWN BUGS:
* 1. silk outlines are sometimes mangled; this is somehow due to
* many overlapping segments. This does not happen in 3Dviewer
* so it is worth inspecting that code to see what is different.
*
* These artefacts can be suppressed for exploratory purposes by
* removing the line width parameter from the length calculation in
* export_vrml_line()
*/
#include <fctsys.h>
#include <fctsys.h>
#include <kicad_string.h>
#include <kicad_string.h>
#include <wxPcbStruct.h>
#include <wxPcbStruct.h>
...
@@ -88,7 +57,7 @@
...
@@ -88,7 +57,7 @@
#define MIN_VRML_LINEWIDTH 0.12
#define MIN_VRML_LINEWIDTH 0.12
// offset for art layers, mm (silk, paste, etc)
// offset for art layers, mm (silk, paste, etc)
#define ART_OFFSET 0.02
#define ART_OFFSET 0.02
5
/* helper function:
/* helper function:
* some characters cannot be used in names,
* some characters cannot be used in names,
...
@@ -183,6 +152,7 @@ public:
...
@@ -183,6 +152,7 @@ public:
VRML_LAYER
bot_silk
;
VRML_LAYER
bot_silk
;
VRML_LAYER
top_tin
;
VRML_LAYER
top_tin
;
VRML_LAYER
bot_tin
;
VRML_LAYER
bot_tin
;
VRML_LAYER
plated_holes
;
double
scale
;
// board internal units to output scaling
double
scale
;
// board internal units to output scaling
double
minLineWidth
;
// minimum width of a VRML line segment
double
minLineWidth
;
// minimum width of a VRML line segment
...
@@ -229,8 +199,18 @@ public:
...
@@ -229,8 +199,18 @@ public:
void
SetOffset
(
double
aXoff
,
double
aYoff
)
void
SetOffset
(
double
aXoff
,
double
aYoff
)
{
{
tx
=
aXoff
;
tx
=
aXoff
;
ty
=
aYoff
;
ty
=
-
aYoff
;
holes
.
SetVertexOffsets
(
aXoff
,
aYoff
);
board
.
SetVertexOffsets
(
aXoff
,
aYoff
);
top_copper
.
SetVertexOffsets
(
aXoff
,
aYoff
);
bot_copper
.
SetVertexOffsets
(
aXoff
,
aYoff
);
top_silk
.
SetVertexOffsets
(
aXoff
,
aYoff
);
bot_silk
.
SetVertexOffsets
(
aXoff
,
aYoff
);
top_tin
.
SetVertexOffsets
(
aXoff
,
aYoff
);
bot_tin
.
SetVertexOffsets
(
aXoff
,
aYoff
);
plated_holes
.
SetVertexOffsets
(
aXoff
,
aYoff
);
}
}
double
GetLayerZ
(
LAYER_NUM
aLayer
)
double
GetLayerZ
(
LAYER_NUM
aLayer
)
...
@@ -278,6 +258,7 @@ public:
...
@@ -278,6 +258,7 @@ public:
bot_silk
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
bot_silk
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
top_tin
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
top_tin
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
bot_tin
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
bot_tin
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
plated_holes
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
return
true
;
return
true
;
}
}
...
@@ -455,6 +436,16 @@ static void write_layers( MODEL_VRML& aModel, std::ofstream& output_file, BOARD*
...
@@ -455,6 +436,16 @@ static void write_layers( MODEL_VRML& aModel, std::ofstream& output_file, BOARD*
-
Millimeter2iu
(
ART_OFFSET
/
2.0
)
*
aModel
.
scale
,
-
Millimeter2iu
(
ART_OFFSET
/
2.0
)
*
aModel
.
scale
,
0
,
aModel
.
precision
);
0
,
aModel
.
precision
);
// VRML_LAYER PTH;
aModel
.
plated_holes
.
Tesselate
(
NULL
,
true
);
write_triangle_bag
(
output_file
,
aModel
.
GetColor
(
VRML_COLOR_TIN
),
&
aModel
.
plated_holes
,
false
,
false
,
aModel
.
GetLayerZ
(
LAST_COPPER_LAYER
)
+
Millimeter2iu
(
ART_OFFSET
/
2.0
)
*
aModel
.
scale
,
aModel
.
GetLayerZ
(
FIRST_COPPER_LAYER
)
-
Millimeter2iu
(
ART_OFFSET
/
2.0
)
*
aModel
.
scale
,
aModel
.
precision
);
// VRML_LAYER top_silk;
// VRML_LAYER top_silk;
aModel
.
top_silk
.
Tesselate
(
&
aModel
.
holes
);
aModel
.
top_silk
.
Tesselate
(
&
aModel
.
holes
);
write_triangle_bag
(
output_file
,
aModel
.
GetColor
(
VRML_COLOR_SILK
),
write_triangle_bag
(
output_file
,
aModel
.
GetColor
(
VRML_COLOR_SILK
),
...
@@ -588,10 +579,10 @@ static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg )
...
@@ -588,10 +579,10 @@ static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg )
{
{
LAYER_NUM
layer
=
drawseg
->
GetLayer
();
LAYER_NUM
layer
=
drawseg
->
GetLayer
();
double
w
=
drawseg
->
GetWidth
()
*
aModel
.
scale
;
double
w
=
drawseg
->
GetWidth
()
*
aModel
.
scale
;
double
x
=
drawseg
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
x
=
drawseg
->
GetStart
().
x
*
aModel
.
scale
;
double
y
=
drawseg
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
y
=
drawseg
->
GetStart
().
y
*
aModel
.
scale
;
double
xf
=
drawseg
->
GetEnd
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
xf
=
drawseg
->
GetEnd
().
x
*
aModel
.
scale
;
double
yf
=
drawseg
->
GetEnd
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
yf
=
drawseg
->
GetEnd
().
y
*
aModel
.
scale
;
// Items on the edge layer are handled elsewhere; just return
// Items on the edge layer are handled elsewhere; just return
if
(
layer
==
EDGE_N
)
if
(
layer
==
EDGE_N
)
...
@@ -626,12 +617,10 @@ static void vrml_text_callback( int x0, int y0, int xf, int yf )
...
@@ -626,12 +617,10 @@ static void vrml_text_callback( int x0, int y0, int xf, int yf )
LAYER_NUM
s_text_layer
=
model_vrml
->
s_text_layer
;
LAYER_NUM
s_text_layer
=
model_vrml
->
s_text_layer
;
int
s_text_width
=
model_vrml
->
s_text_width
;
int
s_text_width
=
model_vrml
->
s_text_width
;
double
scale
=
model_vrml
->
scale
;
double
scale
=
model_vrml
->
scale
;
double
tx
=
model_vrml
->
tx
;
double
ty
=
model_vrml
->
ty
;
export_vrml_line
(
*
model_vrml
,
s_text_layer
,
export_vrml_line
(
*
model_vrml
,
s_text_layer
,
x0
*
scale
+
tx
,
y0
*
scale
+
ty
,
x0
*
scale
,
y0
*
scale
,
xf
*
scale
+
tx
,
yf
*
scale
+
ty
,
xf
*
scale
,
yf
*
scale
,
s_text_width
*
scale
);
s_text_width
*
scale
);
}
}
...
@@ -729,8 +718,6 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
...
@@ -729,8 +718,6 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
}
}
double
scale
=
aModel
.
scale
;
double
scale
=
aModel
.
scale
;
double
dx
=
aModel
.
tx
;
double
dy
=
aModel
.
ty
;
int
i
=
0
;
int
i
=
0
;
int
seg
;
int
seg
;
...
@@ -756,8 +743,8 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
...
@@ -756,8 +743,8 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
if
(
bufferPcbOutlines
[
i
].
end_contour
)
if
(
bufferPcbOutlines
[
i
].
end_contour
)
break
;
break
;
aModel
.
board
.
AddVertex
(
seg
,
bufferPcbOutlines
[
i
].
x
*
scale
+
dx
,
aModel
.
board
.
AddVertex
(
seg
,
bufferPcbOutlines
[
i
].
x
*
scale
,
-
(
bufferPcbOutlines
[
i
].
y
*
scale
+
dy
)
);
-
(
bufferPcbOutlines
[
i
].
y
*
scale
)
);
++
i
;
++
i
;
}
}
...
@@ -788,8 +775,8 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
...
@@ -788,8 +775,8 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
if
(
allLayerHoles
[
i
].
end_contour
)
if
(
allLayerHoles
[
i
].
end_contour
)
break
;
break
;
aModel
.
holes
.
AddVertex
(
seg
,
allLayerHoles
[
i
].
x
*
scale
+
dx
,
aModel
.
holes
.
AddVertex
(
seg
,
allLayerHoles
[
i
].
x
*
scale
,
-
(
allLayerHoles
[
i
].
y
*
scale
+
dy
)
);
-
(
allLayerHoles
[
i
].
y
*
scale
)
);
++
i
;
++
i
;
}
}
...
@@ -849,8 +836,8 @@ static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, const VIA* via )
...
@@ -849,8 +836,8 @@ static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, const VIA* via )
hole
=
via
->
GetDrillValue
()
*
aModel
.
scale
/
2.0
;
hole
=
via
->
GetDrillValue
()
*
aModel
.
scale
/
2.0
;
r
=
via
->
GetWidth
()
*
aModel
.
scale
/
2.0
;
r
=
via
->
GetWidth
()
*
aModel
.
scale
/
2.0
;
x
=
via
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
;
x
=
via
->
GetStart
().
x
*
aModel
.
scale
;
y
=
via
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
;
y
=
via
->
GetStart
().
y
*
aModel
.
scale
;
via
->
LayerPair
(
&
top_layer
,
&
bottom_layer
);
via
->
LayerPair
(
&
top_layer
,
&
bottom_layer
);
// do not render a buried via
// do not render a buried via
...
@@ -873,10 +860,10 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb )
...
@@ -873,10 +860,10 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb )
else
if
(
track
->
GetLayer
()
==
FIRST_COPPER_LAYER
else
if
(
track
->
GetLayer
()
==
FIRST_COPPER_LAYER
||
track
->
GetLayer
()
==
LAST_COPPER_LAYER
)
||
track
->
GetLayer
()
==
LAST_COPPER_LAYER
)
export_vrml_line
(
aModel
,
track
->
GetLayer
(),
export_vrml_line
(
aModel
,
track
->
GetLayer
(),
track
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
,
track
->
GetStart
().
x
*
aModel
.
scale
,
track
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
,
track
->
GetStart
().
y
*
aModel
.
scale
,
track
->
GetEnd
().
x
*
aModel
.
scale
+
aModel
.
tx
,
track
->
GetEnd
().
x
*
aModel
.
scale
,
track
->
GetEnd
().
y
*
aModel
.
scale
+
aModel
.
ty
,
track
->
GetEnd
().
y
*
aModel
.
scale
,
track
->
GetWidth
()
*
aModel
.
scale
);
track
->
GetWidth
()
*
aModel
.
scale
);
}
}
}
}
...
@@ -886,9 +873,6 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
...
@@ -886,9 +873,6 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
{
{
double
scale
=
aModel
.
scale
;
double
scale
=
aModel
.
scale
;
double
dx
=
aModel
.
tx
;
double
dy
=
aModel
.
ty
;
double
x
,
y
;
double
x
,
y
;
for
(
int
ii
=
0
;
ii
<
aPcb
->
GetAreaCount
();
ii
++
)
for
(
int
ii
=
0
;
ii
<
aPcb
->
GetAreaCount
();
ii
++
)
...
@@ -920,8 +904,8 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
...
@@ -920,8 +904,8 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
while
(
i
<
nvert
)
while
(
i
<
nvert
)
{
{
x
=
poly
.
GetX
(
i
)
*
scale
+
dx
;
x
=
poly
.
GetX
(
i
)
*
scale
;
y
=
-
(
poly
.
GetY
(
i
)
*
scale
+
dy
);
y
=
-
(
poly
.
GetY
(
i
)
*
scale
);
if
(
poly
.
IsEndContour
(
i
)
)
if
(
poly
.
IsEndContour
(
i
)
)
break
;
break
;
...
@@ -971,10 +955,10 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
...
@@ -971,10 +955,10 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
double
aOrientation
)
double
aOrientation
)
{
{
LAYER_NUM
layer
=
aOutline
->
GetLayer
();
LAYER_NUM
layer
=
aOutline
->
GetLayer
();
double
x
=
aOutline
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
x
=
aOutline
->
GetStart
().
x
*
aModel
.
scale
;
double
y
=
aOutline
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
y
=
aOutline
->
GetStart
().
y
*
aModel
.
scale
;
double
xf
=
aOutline
->
GetEnd
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
xf
=
aOutline
->
GetEnd
().
x
*
aModel
.
scale
;
double
yf
=
aOutline
->
GetEnd
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
yf
=
aOutline
->
GetEnd
().
y
*
aModel
.
scale
;
double
w
=
aOutline
->
GetWidth
()
*
aModel
.
scale
;
double
w
=
aOutline
->
GetWidth
()
*
aModel
.
scale
;
switch
(
aOutline
->
GetShape
()
)
switch
(
aOutline
->
GetShape
()
)
...
@@ -1015,8 +999,8 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
...
@@ -1015,8 +999,8 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
corner
.
x
+=
aOutline
->
GetPosition
().
x
;
corner
.
x
+=
aOutline
->
GetPosition
().
x
;
corner
.
y
+=
aOutline
->
GetPosition
().
y
;
corner
.
y
+=
aOutline
->
GetPosition
().
y
;
x
=
corner
.
x
*
aModel
.
scale
+
aModel
.
tx
;
x
=
corner
.
x
*
aModel
.
scale
;
y
=
-
(
corner
.
y
*
aModel
.
scale
+
aModel
.
ty
);
y
=
-
(
corner
.
y
*
aModel
.
scale
);
if
(
!
vl
->
AddVertex
(
seg
,
x
,
y
)
)
if
(
!
vl
->
AddVertex
(
seg
,
x
,
y
)
)
throw
(
std
::
runtime_error
(
vl
->
GetError
()
)
);
throw
(
std
::
runtime_error
(
vl
->
GetError
()
)
);
...
@@ -1037,8 +1021,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
...
@@ -1037,8 +1021,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
{
{
// The (maybe offset) pad position
// The (maybe offset) pad position
wxPoint
pad_pos
=
aPad
->
ShapePos
();
wxPoint
pad_pos
=
aPad
->
ShapePos
();
double
pad_x
=
pad_pos
.
x
*
aModel
.
scale
+
aModel
.
tx
;
double
pad_x
=
pad_pos
.
x
*
aModel
.
scale
;
double
pad_y
=
pad_pos
.
y
*
aModel
.
scale
+
aModel
.
ty
;
double
pad_y
=
pad_pos
.
y
*
aModel
.
scale
;
wxSize
pad_delta
=
aPad
->
GetDelta
();
wxSize
pad_delta
=
aPad
->
GetDelta
();
double
pad_dx
=
pad_delta
.
x
*
aModel
.
scale
/
2.0
;
double
pad_dx
=
pad_delta
.
x
*
aModel
.
scale
/
2.0
;
...
@@ -1121,22 +1105,36 @@ static void export_vrml_pad( MODEL_VRML& aModel, BOARD* pcb, D_PAD* aPad )
...
@@ -1121,22 +1105,36 @@ static void export_vrml_pad( MODEL_VRML& aModel, BOARD* pcb, D_PAD* aPad )
double
hole_drill_w
=
(
double
)
aPad
->
GetDrillSize
().
x
*
aModel
.
scale
/
2.0
;
double
hole_drill_w
=
(
double
)
aPad
->
GetDrillSize
().
x
*
aModel
.
scale
/
2.0
;
double
hole_drill_h
=
(
double
)
aPad
->
GetDrillSize
().
y
*
aModel
.
scale
/
2.0
;
double
hole_drill_h
=
(
double
)
aPad
->
GetDrillSize
().
y
*
aModel
.
scale
/
2.0
;
double
hole_drill
=
std
::
min
(
hole_drill_w
,
hole_drill_h
);
double
hole_drill
=
std
::
min
(
hole_drill_w
,
hole_drill_h
);
double
hole_x
=
aPad
->
GetPosition
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
hole_x
=
aPad
->
GetPosition
().
x
*
aModel
.
scale
;
double
hole_y
=
aPad
->
GetPosition
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
hole_y
=
aPad
->
GetPosition
().
y
*
aModel
.
scale
;
// Export the hole on the edge layer
// Export the hole on the edge layer
if
(
hole_drill
>
0
)
if
(
hole_drill
>
0
)
{
{
bool
pth
=
false
;
if
(
aPad
->
GetAttribute
()
!=
PAD_HOLE_NOT_PLATED
)
pth
=
true
;
if
(
aPad
->
GetDrillShape
()
==
PAD_DRILL_OBLONG
)
if
(
aPad
->
GetDrillShape
()
==
PAD_DRILL_OBLONG
)
{
{
// Oblong hole (slot)
// Oblong hole (slot)
aModel
.
holes
.
AddSlot
(
hole_x
,
-
hole_y
,
hole_drill_w
*
2.0
,
hole_drill_h
*
2.0
,
aModel
.
holes
.
AddSlot
(
hole_x
,
-
hole_y
,
hole_drill_w
*
2.0
,
hole_drill_h
*
2.0
,
aPad
->
GetOrientation
()
/
10.0
,
true
);
aPad
->
GetOrientation
()
/
10.0
,
true
,
pth
);
if
(
pth
)
aModel
.
plated_holes
.
AddSlot
(
hole_x
,
-
hole_y
,
hole_drill_w
*
2.0
,
hole_drill_h
*
2.0
,
aPad
->
GetOrientation
()
/
10.0
,
true
,
false
);
}
}
else
else
{
{
// Drill a round hole
// Drill a round hole
aModel
.
holes
.
AddCircle
(
hole_x
,
-
hole_y
,
hole_drill
,
true
);
aModel
.
holes
.
AddCircle
(
hole_x
,
-
hole_y
,
hole_drill
,
true
,
pth
);
if
(
pth
)
aModel
.
plated_holes
.
AddCircle
(
hole_x
,
-
hole_y
,
hole_drill
,
true
,
false
);
}
}
}
}
...
@@ -1390,7 +1388,7 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName,
...
@@ -1390,7 +1388,7 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName,
EDA_RECT
bbbox
=
pcb
->
ComputeBoundingBox
();
EDA_RECT
bbbox
=
pcb
->
ComputeBoundingBox
();
model3d
.
SetOffset
(
-
model3d
.
scale
*
bbbox
.
Centre
().
x
,
model3d
.
SetOffset
(
-
model3d
.
scale
*
bbbox
.
Centre
().
x
,
-
model3d
.
scale
*
bbbox
.
Centre
().
y
);
model3d
.
scale
*
bbbox
.
Centre
().
y
);
output_file
<<
" children [
\n
"
;
output_file
<<
" children [
\n
"
;
...
...
utils/idftools/vrml_layer.cpp
View file @
a91eabb8
...
@@ -23,6 +23,14 @@
...
@@ -23,6 +23,14 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
*/
// Wishlist:
// 1. crop anything outside the board outline on PTH, silk, and copper layers
// 2. on the PTH layer, handle cropped holes differently from others;
// these are assumed to be castellated edges and the profile is not
// a closed loop as assumed for all other outlines.
// 3. a scheme is needed to tell a castellated edge from a plain board edge
#include <iostream>
#include <sstream>
#include <sstream>
#include <string>
#include <string>
#include <iomanip>
#include <iomanip>
...
@@ -137,12 +145,24 @@ static void CALLBACK vrml_tess_err( GLenum errorID, void* user_data )
...
@@ -137,12 +145,24 @@ static void CALLBACK vrml_tess_err( GLenum errorID, void* user_data )
}
}
static
void
CALLBACK
vrml_tess_combine
(
GLdouble
coords
[
3
],
void
*
vertex_data
[
4
],
static
void
CALLBACK
vrml_tess_combine
(
GLdouble
coords
[
3
],
VERTEX_3D
*
vertex_data
[
4
],
GLfloat
weight
[
4
],
void
**
outData
,
void
*
user_data
)
GLfloat
weight
[
4
],
void
**
outData
,
void
*
user_data
)
{
{
VRML_LAYER
*
lp
=
(
VRML_LAYER
*
)
user_data
;
VRML_LAYER
*
lp
=
(
VRML_LAYER
*
)
user_data
;
*
outData
=
lp
->
AddExtraVertex
(
coords
[
0
],
coords
[
1
]
);
// the plating is set to true only if all are plated
bool
plated
=
vertex_data
[
0
]
->
pth
;
if
(
!
vertex_data
[
1
]
->
pth
)
plated
=
false
;
if
(
vertex_data
[
2
]
&&
!
vertex_data
[
2
]
->
pth
)
plated
=
false
;
if
(
vertex_data
[
3
]
&&
!
vertex_data
[
3
]
->
pth
)
plated
=
false
;
*
outData
=
lp
->
AddExtraVertex
(
coords
[
0
],
coords
[
1
],
plated
);
}
}
...
@@ -152,6 +172,8 @@ VRML_LAYER::VRML_LAYER()
...
@@ -152,6 +172,8 @@ VRML_LAYER::VRML_LAYER()
maxArcSeg
=
48
;
maxArcSeg
=
48
;
minSegLength
=
0.1
;
minSegLength
=
0.1
;
maxSegLength
=
0.5
;
maxSegLength
=
0.5
;
offsetX
=
0.0
;
offsetY
=
0.0
;
fix
=
false
;
fix
=
false
;
Fault
=
false
;
Fault
=
false
;
...
@@ -230,6 +252,8 @@ void VRML_LAYER::Clear( void )
...
@@ -230,6 +252,8 @@ void VRML_LAYER::Clear( void )
contours
.
pop_back
();
contours
.
pop_back
();
}
}
pth
.
clear
();
areas
.
clear
();
areas
.
clear
();
for
(
i
=
vertices
.
size
();
i
>
0
;
--
i
)
for
(
i
=
vertices
.
size
();
i
>
0
;
--
i
)
...
@@ -254,6 +278,7 @@ void VRML_LAYER::clearTmp( void )
...
@@ -254,6 +278,7 @@ void VRML_LAYER::clearTmp( void )
glcmd
=
0
;
glcmd
=
0
;
triplets
.
clear
();
triplets
.
clear
();
solid
.
clear
();
for
(
i
=
outline
.
size
();
i
>
0
;
--
i
)
for
(
i
=
outline
.
size
();
i
>
0
;
--
i
)
{
{
...
@@ -283,7 +308,7 @@ void VRML_LAYER::clearTmp( void )
...
@@ -283,7 +308,7 @@ void VRML_LAYER::clearTmp( void )
// create a new contour to be populated; returns an index
// create a new contour to be populated; returns an index
// into the contour list or -1 if there are problems
// into the contour list or -1 if there are problems
int
VRML_LAYER
::
NewContour
(
void
)
int
VRML_LAYER
::
NewContour
(
bool
aPlatedHole
)
{
{
if
(
fix
)
if
(
fix
)
return
-
1
;
return
-
1
;
...
@@ -296,6 +321,8 @@ int VRML_LAYER::NewContour( void )
...
@@ -296,6 +321,8 @@ int VRML_LAYER::NewContour( void )
contours
.
push_back
(
contour
);
contours
.
push_back
(
contour
);
areas
.
push_back
(
0.0
);
areas
.
push_back
(
0.0
);
pth
.
push_back
(
aPlatedHole
);
return
contours
.
size
()
-
1
;
return
contours
.
size
()
-
1
;
}
}
...
@@ -329,6 +356,7 @@ bool VRML_LAYER::AddVertex( int aContourID, double aXpos, double aYpos )
...
@@ -329,6 +356,7 @@ bool VRML_LAYER::AddVertex( int aContourID, double aXpos, double aYpos )
vertex
->
y
=
aYpos
;
vertex
->
y
=
aYpos
;
vertex
->
i
=
idx
++
;
vertex
->
i
=
idx
++
;
vertex
->
o
=
-
1
;
vertex
->
o
=
-
1
;
vertex
->
pth
=
pth
[
aContourID
];
VERTEX_3D
*
v2
=
NULL
;
VERTEX_3D
*
v2
=
NULL
;
...
@@ -440,9 +468,15 @@ bool VRML_LAYER::AppendCircle( double aXpos, double aYpos,
...
@@ -440,9 +468,15 @@ bool VRML_LAYER::AppendCircle( double aXpos, double aYpos,
// adds a circle the existing list; if 'hole' is true the contour is
// adds a circle the existing list; if 'hole' is true the contour is
// a hole. Returns true if OK.
// a hole. Returns true if OK.
bool
VRML_LAYER
::
AddCircle
(
double
aXpos
,
double
aYpos
,
double
aRadius
,
bool
aHoleFlag
)
bool
VRML_LAYER
::
AddCircle
(
double
aXpos
,
double
aYpos
,
double
aRadius
,
bool
aHoleFlag
,
bool
aPlatedHole
)
{
{
int
pad
=
NewContour
();
int
pad
;
if
(
aHoleFlag
&&
aPlatedHole
)
pad
=
NewContour
(
true
);
else
pad
=
NewContour
(
false
);
if
(
pad
<
0
)
if
(
pad
<
0
)
{
{
...
@@ -458,7 +492,7 @@ bool VRML_LAYER::AddCircle( double aXpos, double aYpos, double aRadius, bool aHo
...
@@ -458,7 +492,7 @@ bool VRML_LAYER::AddCircle( double aXpos, double aYpos, double aRadius, bool aHo
// contour is a hole. Returns true if OK.
// contour is a hole. Returns true if OK.
bool
VRML_LAYER
::
AddSlot
(
double
aCenterX
,
double
aCenterY
,
bool
VRML_LAYER
::
AddSlot
(
double
aCenterX
,
double
aCenterY
,
double
aSlotLength
,
double
aSlotWidth
,
double
aSlotLength
,
double
aSlotWidth
,
double
aAngle
,
bool
aHoleFlag
)
double
aAngle
,
bool
aHoleFlag
,
bool
aPlatedHole
)
{
{
aAngle
*=
M_PI
/
180.0
;
aAngle
*=
M_PI
/
180.0
;
...
@@ -480,7 +514,12 @@ bool VRML_LAYER::AddSlot( double aCenterX, double aCenterY,
...
@@ -480,7 +514,12 @@ bool VRML_LAYER::AddSlot( double aCenterX, double aCenterY,
double
ang
,
da
;
double
ang
,
da
;
int
i
;
int
i
;
int
pad
=
NewContour
();
int
pad
;
if
(
aHoleFlag
&&
aPlatedHole
)
pad
=
NewContour
(
true
);
else
pad
=
NewContour
(
false
);
if
(
pad
<
0
)
if
(
pad
<
0
)
{
{
...
@@ -578,7 +617,7 @@ bool VRML_LAYER::AppendArc( double aCenterX, double aCenterY, double aRadius,
...
@@ -578,7 +617,7 @@ bool VRML_LAYER::AppendArc( double aCenterX, double aCenterY, double aRadius,
// adds an arc with the given center, start point, pen width, and angle (degrees).
// adds an arc with the given center, start point, pen width, and angle (degrees).
bool
VRML_LAYER
::
AddArc
(
double
aCenterX
,
double
aCenterY
,
double
aStartX
,
double
aStartY
,
bool
VRML_LAYER
::
AddArc
(
double
aCenterX
,
double
aCenterY
,
double
aStartX
,
double
aStartY
,
double
aArcWidth
,
double
aAngle
,
bool
aHoleFlag
)
double
aArcWidth
,
double
aAngle
,
bool
aHoleFlag
,
bool
aPlatedHole
)
{
{
aAngle
*=
M_PI
/
180.0
;
aAngle
*=
M_PI
/
180.0
;
...
@@ -636,7 +675,12 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
...
@@ -636,7 +675,12 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
std
::
swap
(
iendy
,
isty
);
std
::
swap
(
iendy
,
isty
);
}
}
int
arc
=
NewContour
();
int
arc
;
if
(
aHoleFlag
&&
aPlatedHole
)
arc
=
NewContour
(
true
);
else
arc
=
NewContour
(
false
);
if
(
arc
<
0
)
if
(
arc
<
0
)
{
{
...
@@ -688,7 +732,7 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
...
@@ -688,7 +732,7 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
// tesselates the contours in preparation for a 3D output;
// tesselates the contours in preparation for a 3D output;
// returns true if all was fine, false otherwise
// returns true if all was fine, false otherwise
bool
VRML_LAYER
::
Tesselate
(
VRML_LAYER
*
holes
)
bool
VRML_LAYER
::
Tesselate
(
VRML_LAYER
*
holes
,
bool
aHolesOnly
)
{
{
if
(
!
tess
)
if
(
!
tess
)
{
{
...
@@ -699,6 +743,12 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
...
@@ -699,6 +743,12 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
pholes
=
holes
;
pholes
=
holes
;
Fault
=
false
;
Fault
=
false
;
if
(
aHolesOnly
)
gluTessProperty
(
tess
,
GLU_TESS_WINDING_RULE
,
GLU_TESS_WINDING_NEGATIVE
);
else
gluTessProperty
(
tess
,
GLU_TESS_WINDING_RULE
,
GLU_TESS_WINDING_POSITIVE
);
if
(
contours
.
size
()
<
1
||
vertices
.
size
()
<
3
)
if
(
contours
.
size
()
<
1
||
vertices
.
size
()
<
3
)
{
{
error
=
"Tesselate(): not enough vertices"
;
error
=
"Tesselate(): not enough vertices"
;
...
@@ -736,9 +786,37 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
...
@@ -736,9 +786,37 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
eidx
=
idx
+
hidx
;
eidx
=
idx
+
hidx
;
if
(
aHolesOnly
&&
(
checkNContours
(
true
)
==
0
)
)
{
error
=
"tesselate(): no hole contours"
;
return
false
;
}
else
if
(
!
aHolesOnly
&&
(
checkNContours
(
false
)
==
0
)
)
{
error
=
"tesselate(): no solid contours"
;
return
false
;
}
// open the polygon
// open the polygon
gluTessBeginPolygon
(
tess
,
this
);
gluTessBeginPolygon
(
tess
,
this
);
if
(
aHolesOnly
)
{
pholes
=
NULL
;
// do not accept foreign holes
hidx
=
0
;
eidx
=
idx
;
// add holes
pushVertices
(
true
);
gluTessEndPolygon
(
tess
);
if
(
Fault
)
return
false
;
return
true
;
}
// add solid outlines
// add solid outlines
pushVertices
(
false
);
pushVertices
(
false
);
...
@@ -748,6 +826,13 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
...
@@ -748,6 +826,13 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
if
(
Fault
)
if
(
Fault
)
return
false
;
return
false
;
// if there are no outlines we cannot proceed
if
(
outline
.
empty
()
)
{
error
=
"tesselate(): no points in result"
;
return
false
;
}
// at this point we have a solid outline; add it to the tesselator
// at this point we have a solid outline; add it to the tesselator
gluTessBeginPolygon
(
tess
,
this
);
gluTessBeginPolygon
(
tess
,
this
);
...
@@ -793,6 +878,7 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
...
@@ -793,6 +878,7 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
// close the polygon; this creates the outline points
// close the polygon; this creates the outline points
// and the point ordering list 'ordmap'
// and the point ordering list 'ordmap'
solid
.
clear
();
gluTessEndPolygon
(
tess
);
gluTessEndPolygon
(
tess
);
// repeat the last operation but request a tesselated surface
// repeat the last operation but request a tesselated surface
...
@@ -825,6 +911,8 @@ bool VRML_LAYER::pushOutline( VRML_LAYER* holes )
...
@@ -825,6 +911,8 @@ bool VRML_LAYER::pushOutline( VRML_LAYER* holes )
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
obeg
=
outline
.
begin
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
obeg
=
outline
.
begin
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
oend
=
outline
.
end
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
oend
=
outline
.
end
();
int
nc
=
0
;
// number of contours pushed
int
pi
;
int
pi
;
std
::
list
<
int
>::
const_iterator
begin
;
std
::
list
<
int
>::
const_iterator
begin
;
std
::
list
<
int
>::
const_iterator
end
;
std
::
list
<
int
>::
const_iterator
end
;
...
@@ -876,6 +964,13 @@ bool VRML_LAYER::pushOutline( VRML_LAYER* holes )
...
@@ -876,6 +964,13 @@ bool VRML_LAYER::pushOutline( VRML_LAYER* holes )
gluTessEndContour
(
tess
);
gluTessEndContour
(
tess
);
++
obeg
;
++
obeg
;
++
nc
;
}
if
(
!
nc
)
{
error
=
"pushOutline():: no valid contours available"
;
return
false
;
}
}
return
true
;
return
true
;
...
@@ -902,7 +997,7 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPr
...
@@ -902,7 +997,7 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPr
return
false
;
return
false
;
std
::
string
strx
,
stry
,
strz
;
std
::
string
strx
,
stry
,
strz
;
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
FormatSinglet
(
aZcoord
,
aPrecision
,
strz
);
FormatSinglet
(
aZcoord
,
aPrecision
,
strz
);
aOutFile
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
aOutFile
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
@@ -914,7 +1009,7 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPr
...
@@ -914,7 +1009,7 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPr
if
(
!
vp
)
if
(
!
vp
)
return
false
;
return
false
;
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
if
(
i
&
1
)
if
(
i
&
1
)
aOutFile
<<
", "
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
aOutFile
<<
", "
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
@@ -954,7 +1049,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
...
@@ -954,7 +1049,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
return
false
;
return
false
;
std
::
string
strx
,
stry
,
strz
;
std
::
string
strx
,
stry
,
strz
;
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
FormatSinglet
(
aTopZ
,
aPrecision
,
strz
);
FormatSinglet
(
aTopZ
,
aPrecision
,
strz
);
aOutFile
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
aOutFile
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
@@ -966,7 +1061,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
...
@@ -966,7 +1061,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
if
(
!
vp
)
if
(
!
vp
)
return
false
;
return
false
;
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
if
(
i
&
1
)
if
(
i
&
1
)
aOutFile
<<
", "
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
aOutFile
<<
", "
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
@@ -976,7 +1071,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
...
@@ -976,7 +1071,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
// repeat for the bottom layer
// repeat for the bottom layer
vp
=
getVertexByIndex
(
ordmap
[
0
],
pholes
);
vp
=
getVertexByIndex
(
ordmap
[
0
],
pholes
);
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
FormatSinglet
(
aBottomZ
,
aPrecision
,
strz
);
FormatSinglet
(
aBottomZ
,
aPrecision
,
strz
);
bool
endl
;
bool
endl
;
...
@@ -995,7 +1090,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
...
@@ -995,7 +1090,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
for
(
i
=
1
,
j
=
ordmap
.
size
();
i
<
j
;
++
i
)
for
(
i
=
1
,
j
=
ordmap
.
size
();
i
<
j
;
++
i
)
{
{
vp
=
getVertexByIndex
(
ordmap
[
i
],
pholes
);
vp
=
getVertexByIndex
(
ordmap
[
i
],
pholes
);
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
if
(
endl
)
if
(
endl
)
{
{
...
@@ -1064,68 +1159,73 @@ bool VRML_LAYER::WriteIndices( bool aTopFlag, std::ofstream& aOutFile )
...
@@ -1064,68 +1159,73 @@ bool VRML_LAYER::WriteIndices( bool aTopFlag, std::ofstream& aOutFile )
// writes out the index list for a 3D feature
// writes out the index list for a 3D feature
bool
VRML_LAYER
::
Write3DIndices
(
std
::
ofstream
&
aOutFile
)
bool
VRML_LAYER
::
Write3DIndices
(
std
::
ofstream
&
aOutFile
,
bool
aIncludePlatedHoles
)
{
{
if
(
triplets
.
empty
()
)
{
error
=
"Write3DIndices(): no triplets (triangular facets) to write"
;
return
false
;
}
if
(
outline
.
empty
()
)
if
(
outline
.
empty
()
)
{
{
error
=
"WriteIndices(): no outline available"
;
error
=
"WriteIndices(): no outline available"
;
return
false
;
return
false
;
}
}
// go through the triplet list and write out the indices based on order
char
mark
;
std
::
list
<
TRIPLET_3D
>::
const_iterator
tbeg
=
triplets
.
begin
();
bool
holes_only
=
triplets
.
empty
();
std
::
list
<
TRIPLET_3D
>::
const_iterator
tend
=
triplets
.
end
();
int
i
=
1
;
int
i
=
1
;
int
idx2
=
ordmap
.
size
();
// index to the bottom vertices
int
idx2
=
ordmap
.
size
();
// index to the bottom vertices
// print out the top vertices
if
(
!
holes_only
)
aOutFile
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
++
tbeg
;
while
(
tbeg
!=
tend
)
{
{
if
(
(
i
++
&
7
)
==
4
)
mark
=
','
;
{
i
=
1
;
aOutFile
<<
",
\n
"
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
}
else
{
aOutFile
<<
", "
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
}
++
tbeg
;
// go through the triplet list and write out the indices based on order
}
std
::
list
<
TRIPLET_3D
>::
const_iterator
tbeg
=
triplets
.
begin
();
std
::
list
<
TRIPLET_3D
>::
const_iterator
tend
=
triplets
.
end
();
// print out the bottom vertices
// print out the top vertices
tbeg
=
triplets
.
begin
();
aOutFile
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
++
tbeg
;
while
(
tbeg
!=
tend
)
while
(
tbeg
!=
tend
)
{
if
(
(
i
++
&
7
)
==
4
)
{
{
i
=
1
;
if
(
(
i
++
&
7
)
==
4
)
aOutFile
<<
",
\n
"
<<
(
tbeg
->
i2
+
idx2
)
<<
", "
<<
(
tbeg
->
i1
+
idx2
)
<<
", "
<<
(
tbeg
->
i3
+
idx2
)
<<
", -1"
;
{
i
=
1
;
aOutFile
<<
",
\n
"
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
}
else
{
aOutFile
<<
", "
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
}
++
tbeg
;
}
}
else
// print out the bottom vertices
tbeg
=
triplets
.
begin
();
while
(
tbeg
!=
tend
)
{
{
aOutFile
<<
", "
<<
(
tbeg
->
i2
+
idx2
)
<<
", "
<<
(
tbeg
->
i1
+
idx2
)
<<
", "
<<
(
tbeg
->
i3
+
idx2
)
<<
", -1"
;
if
(
(
i
++
&
7
)
==
4
)
}
{
i
=
1
;
aOutFile
<<
",
\n
"
<<
(
tbeg
->
i2
+
idx2
)
<<
", "
<<
(
tbeg
->
i1
+
idx2
)
<<
", "
<<
(
tbeg
->
i3
+
idx2
)
<<
", -1"
;
}
else
{
aOutFile
<<
", "
<<
(
tbeg
->
i2
+
idx2
)
<<
", "
<<
(
tbeg
->
i1
+
idx2
)
<<
", "
<<
(
tbeg
->
i3
+
idx2
)
<<
", -1"
;
}
++
tbeg
;
++
tbeg
;
}
}
}
else
mark
=
' '
;
// print out indices for the walls joining top to bottom
// print out indices for the walls joining top to bottom
int
firstPoint
;
int
lastPoint
;
int
lastPoint
;
int
curPoint
;
int
curPoint
;
int
curContour
=
0
;
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
obeg
=
outline
.
begin
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
obeg
=
outline
.
begin
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
oend
=
outline
.
end
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
oend
=
outline
.
end
();
...
@@ -1141,22 +1241,71 @@ bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile )
...
@@ -1141,22 +1241,71 @@ bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile )
if
(
cp
->
size
()
<
3
)
if
(
cp
->
size
()
<
3
)
{
{
++
obeg
;
++
obeg
;
++
curContour
;
continue
;
continue
;
}
}
cbeg
=
cp
->
begin
();
cbeg
=
cp
->
begin
();
cend
=
cp
->
end
();
cend
=
cp
->
end
();
lastPoint
=
*
(
cbeg
++
);
firstPoint
=
*
(
cbeg
++
);
// skip all PTH vertices which are not in a solid outline
lastPoint
=
firstPoint
;
if
(
!
aIncludePlatedHoles
&&
!
solid
[
curContour
]
&&
getVertexByIndex
(
ordmap
[
lastPoint
],
pholes
)
->
pth
)
{
++
obeg
;
++
curContour
;
continue
;
}
while
(
cbeg
!=
cend
)
while
(
cbeg
!=
cend
)
{
{
curPoint
=
*
(
cbeg
++
);
curPoint
=
*
(
cbeg
++
);
if
(
!
holes_only
)
{
if
(
(
i
++
&
3
)
==
2
)
{
i
=
1
;
aOutFile
<<
mark
<<
"
\n
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
else
{
aOutFile
<<
mark
<<
" "
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
}
else
{
if
(
(
i
++
&
3
)
==
2
)
{
i
=
1
;
aOutFile
<<
mark
<<
"
\n
"
<<
curPoint
<<
", "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
+
idx2
<<
", "
<<
lastPoint
<<
", -1"
;
}
else
{
aOutFile
<<
mark
<<
" "
<<
curPoint
<<
", "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
+
idx2
<<
", "
<<
lastPoint
<<
", -1"
;
}
}
mark
=
','
;
lastPoint
=
curPoint
;
}
// check if the loop needs to be closed
cbeg
=
cp
->
begin
();
cend
=
--
cp
->
end
();
curPoint
=
*
(
cbeg
);
lastPoint
=
*
(
cend
);
if
(
!
holes_only
)
{
if
(
(
i
++
&
3
)
==
2
)
if
(
(
i
++
&
3
)
==
2
)
{
{
i
=
1
;
aOutFile
<<
",
\n
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
",
\n
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
}
...
@@ -1165,21 +1314,23 @@ bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile )
...
@@ -1165,21 +1314,23 @@ bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile )
aOutFile
<<
", "
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", "
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
}
lastPoint
=
curPoint
;
}
if
(
(
i
++
&
3
)
==
2
)
{
aOutFile
<<
",
\n
"
<<
firstPoint
<<
", "
<<
lastPoint
<<
", "
<<
firstPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
firstPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
}
else
else
{
{
aOutFile
<<
", "
<<
firstPoint
<<
", "
<<
lastPoint
<<
", "
<<
firstPoint
+
idx2
;
if
(
(
i
++
&
3
)
==
2
)
aOutFile
<<
", -1, "
<<
firstPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
{
aOutFile
<<
",
\n
"
<<
curPoint
<<
", "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
+
idx2
<<
", "
<<
lastPoint
<<
", -1"
;
}
else
{
aOutFile
<<
", "
<<
curPoint
<<
", "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
+
idx2
<<
", "
<<
lastPoint
<<
", -1"
;
}
}
}
++
obeg
;
++
obeg
;
++
curContour
;
}
}
return
!
aOutFile
.
fail
();
return
!
aOutFile
.
fail
();
...
@@ -1222,7 +1373,7 @@ bool VRML_LAYER::addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 )
...
@@ -1222,7 +1373,7 @@ bool VRML_LAYER::addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 )
// add an extra vertex (to be called only by the COMBINE callback)
// add an extra vertex (to be called only by the COMBINE callback)
VERTEX_3D
*
VRML_LAYER
::
AddExtraVertex
(
double
aXpos
,
double
aYpos
)
VERTEX_3D
*
VRML_LAYER
::
AddExtraVertex
(
double
aXpos
,
double
aYpos
,
bool
aPlatedHole
)
{
{
VERTEX_3D
*
vertex
=
new
VERTEX_3D
;
VERTEX_3D
*
vertex
=
new
VERTEX_3D
;
...
@@ -1239,6 +1390,7 @@ VERTEX_3D* VRML_LAYER::AddExtraVertex( double aXpos, double aYpos )
...
@@ -1239,6 +1390,7 @@ VERTEX_3D* VRML_LAYER::AddExtraVertex( double aXpos, double aYpos )
vertex
->
y
=
aYpos
;
vertex
->
y
=
aYpos
;
vertex
->
i
=
eidx
++
;
vertex
->
i
=
eidx
++
;
vertex
->
o
=
-
1
;
vertex
->
o
=
-
1
;
vertex
->
pth
=
aPlatedHole
;
extra_verts
.
push_back
(
vertex
);
extra_verts
.
push_back
(
vertex
);
...
@@ -1282,12 +1434,39 @@ void VRML_LAYER::glEnd( void )
...
@@ -1282,12 +1434,39 @@ void VRML_LAYER::glEnd( void )
if
(
!
loop
)
if
(
!
loop
)
break
;
break
;
for
(
unsigned
int
i
=
0
;
i
<
vlist
.
size
();
++
i
)
double
firstX
=
0.0
;
double
firstY
=
0.0
;
double
lastX
,
lastY
;
double
curX
,
curY
;
double
area
=
0.0
;
if
(
vlist
.
size
()
>
0
)
{
loop
->
push_back
(
vlist
[
0
]
->
o
);
firstX
=
vlist
[
0
]
->
x
;
firstY
=
vlist
[
0
]
->
y
;
lastX
=
firstX
;
lastY
=
firstY
;
}
for
(
size_t
i
=
1
;
i
<
vlist
.
size
();
++
i
)
{
{
loop
->
push_back
(
vlist
[
i
]
->
o
);
loop
->
push_back
(
vlist
[
i
]
->
o
);
curX
=
vlist
[
i
]
->
x
;
curY
=
vlist
[
i
]
->
y
;
area
+=
(
curX
-
lastX
)
*
(
curY
+
lastY
);
lastX
=
curX
;
lastY
=
curY
;
}
}
area
+=
(
firstX
-
lastX
)
*
(
firstY
+
lastY
);
outline
.
push_back
(
loop
);
outline
.
push_back
(
loop
);
if
(
area
<=
0.0
)
solid
.
push_back
(
true
);
else
solid
.
push_back
(
false
);
}
}
break
;
break
;
...
@@ -1398,6 +1577,31 @@ void VRML_LAYER::processTri( void )
...
@@ -1398,6 +1577,31 @@ void VRML_LAYER::processTri( void )
}
}
int
VRML_LAYER
::
checkNContours
(
bool
holes
)
{
int
nc
=
0
;
// number of contours
if
(
contours
.
empty
()
)
return
0
;
std
::
list
<
int
>::
const_iterator
begin
;
std
::
list
<
int
>::
const_iterator
end
;
for
(
size_t
i
=
0
;
i
<
contours
.
size
();
++
i
)
{
if
(
contours
[
i
]
->
size
()
<
3
)
continue
;
if
(
(
holes
&&
areas
[
i
]
<=
0.0
)
||
(
!
holes
&&
areas
[
i
]
>
0.0
)
)
continue
;
++
nc
;
}
return
nc
;
}
// push the internally held vertices
// push the internally held vertices
void
VRML_LAYER
::
pushVertices
(
bool
holes
)
void
VRML_LAYER
::
pushVertices
(
bool
holes
)
{
{
...
@@ -1434,6 +1638,8 @@ void VRML_LAYER::pushVertices( bool holes )
...
@@ -1434,6 +1638,8 @@ void VRML_LAYER::pushVertices( bool holes )
gluTessEndContour
(
tess
);
gluTessEndContour
(
tess
);
}
}
return
;
}
}
...
@@ -1564,3 +1770,11 @@ const std::string& VRML_LAYER::GetError( void )
...
@@ -1564,3 +1770,11 @@ const std::string& VRML_LAYER::GetError( void )
{
{
return
error
;
return
error
;
}
}
void
VRML_LAYER
::
SetVertexOffsets
(
double
aXoffset
,
double
aYoffset
)
{
offsetX
=
aXoffset
;
offsetY
=
aYoffset
;
return
;
}
utils/idftools/vrml_layer.h
View file @
a91eabb8
...
@@ -70,6 +70,7 @@ struct VERTEX_3D
...
@@ -70,6 +70,7 @@ struct VERTEX_3D
double
y
;
double
y
;
int
i
;
// vertex index
int
i
;
// vertex index
int
o
;
// vertex order
int
o
;
// vertex order
bool
pth
;
// true for plate-through hole
};
};
struct
TRIPLET_3D
struct
TRIPLET_3D
...
@@ -93,12 +94,18 @@ private:
...
@@ -93,12 +94,18 @@ private:
double
minSegLength
;
// min. segment length
double
minSegLength
;
// min. segment length
double
maxSegLength
;
// max. segment length
double
maxSegLength
;
// max. segment length
// Vertex offsets to work around a suspected GLU tesselator bug
double
offsetX
;
double
offsetY
;
bool
fix
;
// when true, no more vertices may be added by the user
bool
fix
;
// when true, no more vertices may be added by the user
int
idx
;
// vertex index (number of contained vertices)
int
idx
;
// vertex index (number of contained vertices)
int
ord
;
// vertex order (number of ordered vertices)
int
ord
;
// vertex order (number of ordered vertices)
unsigned
int
idxout
;
// outline index to first point in 3D outline
unsigned
int
idxout
;
// outline index to first point in 3D outline
std
::
vector
<
VERTEX_3D
*>
vertices
;
// vertices of all contours
std
::
vector
<
VERTEX_3D
*>
vertices
;
// vertices of all contours
std
::
vector
<
std
::
list
<
int
>*>
contours
;
// lists of vertices for each contour
std
::
vector
<
std
::
list
<
int
>*>
contours
;
// lists of vertices for each contour
std
::
vector
<
bool
>
pth
;
// indicates whether a 'contour' is a PTH or not
std
::
vector
<
bool
>
solid
;
// indicates whether a 'contour' is a solid or a hole
std
::
vector
<
double
>
areas
;
// area of the contours (positive if winding is CCW)
std
::
vector
<
double
>
areas
;
// area of the contours (positive if winding is CCW)
std
::
list
<
TRIPLET_3D
>
triplets
;
// output facet triplet list (triplet of ORDER values)
std
::
list
<
TRIPLET_3D
>
triplets
;
// output facet triplet list (triplet of ORDER values)
std
::
list
<
std
::
list
<
int
>*>
outline
;
// indices for outline outputs (index by ORDER values)
std
::
list
<
std
::
list
<
int
>*>
outline
;
// indices for outline outputs (index by ORDER values)
...
@@ -136,6 +143,9 @@ private:
...
@@ -136,6 +143,9 @@ private:
// calculate number of sides on an arc (angle is in radians)
// calculate number of sides on an arc (angle is in radians)
int
calcNSides
(
double
aRadius
,
double
aAngle
);
int
calcNSides
(
double
aRadius
,
double
aAngle
);
// returns the number of solid or hole contours
int
checkNContours
(
bool
holes
);
public
:
public
:
/// set to true when a fault is encountered during tesselation
/// set to true when a fault is encountered during tesselation
bool
Fault
;
bool
Fault
;
...
@@ -191,9 +201,11 @@ public:
...
@@ -191,9 +201,11 @@ public:
* Function NewContour
* Function NewContour
* creates a new list of vertices and returns an index to the list
* creates a new list of vertices and returns an index to the list
*
*
* @param aPlatedHole is true if the new contour will represent a plated hole
*
* @return int: index to the list or -1 if the operation failed
* @return int: index to the list or -1 if the operation failed
*/
*/
int
NewContour
(
void
);
int
NewContour
(
bool
aPlatedHole
=
false
);
/**
/**
* Function AddVertex
* Function AddVertex
...
@@ -231,7 +243,8 @@ public:
...
@@ -231,7 +243,8 @@ public:
*
*
* @return bool: true if the new contour was successfully created
* @return bool: true if the new contour was successfully created
*/
*/
bool
AppendCircle
(
double
aXpos
,
double
aYpos
,
double
aRadius
,
int
aContourID
,
bool
aHoleFlag
=
false
);
bool
AppendCircle
(
double
aXpos
,
double
aYpos
,
double
aRadius
,
int
aContourID
,
bool
aHoleFlag
=
false
);
/**
/**
* Function AddCircle
* Function AddCircle
...
@@ -241,10 +254,12 @@ public:
...
@@ -241,10 +254,12 @@ public:
* @param aYpos is the Y coordinate of the hole center
* @param aYpos is the Y coordinate of the hole center
* @param aRadius is the radius of the hole
* @param aRadius is the radius of the hole
* @param aHoleFlag determines if the contour to be created is a cutout
* @param aHoleFlag determines if the contour to be created is a cutout
* @param aPlatedHole is true if this is a plated hole
*
*
* @return bool: true if the new contour was successfully created
* @return bool: true if the new contour was successfully created
*/
*/
bool
AddCircle
(
double
aXpos
,
double
aYpos
,
double
aRadius
,
bool
aHoleFlag
=
false
);
bool
AddCircle
(
double
aXpos
,
double
aYpos
,
double
aRadius
,
bool
aHoleFlag
=
false
,
bool
aPlatedHole
=
false
);
/**
/**
* Function AddSlot
* Function AddSlot
...
@@ -256,11 +271,12 @@ public:
...
@@ -256,11 +271,12 @@ public:
* @param aSlotWidth is the width of the slot along the minor axis
* @param aSlotWidth is the width of the slot along the minor axis
* @param aAngle (degrees) is the orientation of the slot
* @param aAngle (degrees) is the orientation of the slot
* @param aHoleFlag determines whether the slot is a hole or a solid
* @param aHoleFlag determines whether the slot is a hole or a solid
* @param aPlatedHole is true if this is a plated slot
*
*
* @return bool: true if the slot was successfully created
* @return bool: true if the slot was successfully created
*/
*/
bool
AddSlot
(
double
aCenterX
,
double
aCenterY
,
double
aSlotLength
,
double
aSlotWidth
,
bool
AddSlot
(
double
aCenterX
,
double
aCenterY
,
double
aSlotLength
,
double
aSlotWidth
,
double
aAngle
,
bool
aHoleFlag
=
false
);
double
aAngle
,
bool
aHoleFlag
=
false
,
bool
aPlatedHole
=
false
);
/**
/**
* Function AppendArc
* Function AppendArc
...
@@ -289,11 +305,14 @@ public:
...
@@ -289,11 +305,14 @@ public:
* @param aArcWidth is the width of the arc
* @param aArcWidth is the width of the arc
* @param aAngle is the included angle (degrees)
* @param aAngle is the included angle (degrees)
* @param aHoleFlag determines whether the arc is to be a hole or a solid
* @param aHoleFlag determines whether the arc is to be a hole or a solid
* @param aPlatedHole is true if this is a plated slotted arc
*
*
* @return bool: true if the feature was successfully created
* @return bool: true if the feature was successfully created
*/
*/
bool
AddArc
(
double
aCenterX
,
double
aCenterY
,
double
aStartX
,
double
aStartY
,
bool
AddArc
(
double
aCenterX
,
double
aCenterY
,
double
aArcWidth
,
double
aAngle
,
bool
aHoleFlag
=
false
);
double
aStartX
,
double
aStartY
,
double
aArcWidth
,
double
aAngle
,
bool
aHoleFlag
=
false
,
bool
aPlatedHole
=
false
);
/**
/**
* Function Tesselate
* Function Tesselate
...
@@ -301,11 +320,12 @@ public:
...
@@ -301,11 +320,12 @@ public:
* vertex sets required to render the surface.
* vertex sets required to render the surface.
*
*
* @param holes is an optional pointer to cutouts to be imposed on the
* @param holes is an optional pointer to cutouts to be imposed on the
* surface.
* surface.
* @param aHolesOnly is true if the outline contains only holes
*
*
* @return bool: true if the operation succeeded
* @return bool: true if the operation succeeded
*/
*/
bool
Tesselate
(
VRML_LAYER
*
holes
=
NULL
);
bool
Tesselate
(
VRML_LAYER
*
holes
=
NULL
,
bool
aHolesOnly
=
false
);
/**
/**
* Function WriteVertices
* Function WriteVertices
...
@@ -351,19 +371,26 @@ public:
...
@@ -351,19 +371,26 @@ public:
* writes out the vertex sets required to render an extruded solid
* writes out the vertex sets required to render an extruded solid
*
*
* @param aOutFile is the file to write to
* @param aOutFile is the file to write to
* @param aIncludePlatedHoles is true if holes marked as plated should
* be rendered. Default is false since the user will usually
* render these holes in a different color
*
*
* @return bool: true if the operation succeeded
* @return bool: true if the operation succeeded
*/
*/
bool
Write3DIndices
(
std
::
ofstream
&
aOutFile
);
bool
Write3DIndices
(
std
::
ofstream
&
aOutFile
,
bool
aIncludePlatedHoles
=
false
);
/**
/**
* Function AddExtraVertex
* Function AddExtraVertex
* adds an extra vertex as required by the GLU tesselator
* adds an extra vertex as required by the GLU tesselator.
*
* @param aXpos is the X coordinate of the newly created point
* @param aYpos is the Y coordinate of the newly created point
* @param aPlatedHole is true if this point is part of a plated hole
*
*
* @return VERTEX_3D*: is the new vertex or NULL if a vertex
* @return VERTEX_3D*: is the new vertex or NULL if a vertex
* could not be created.
* could not be created.
*/
*/
VERTEX_3D
*
AddExtraVertex
(
double
aXpos
,
double
aYpos
);
VERTEX_3D
*
AddExtraVertex
(
double
aXpos
,
double
aYpos
,
bool
aPlatedHole
);
/**
/**
* Function glStart
* Function glStart
...
@@ -429,6 +456,8 @@ public:
...
@@ -429,6 +456,8 @@ public:
* Returns the error message related to the last failed operation
* Returns the error message related to the last failed operation
*/
*/
const
std
::
string
&
GetError
(
void
);
const
std
::
string
&
GetError
(
void
);
void
SetVertexOffsets
(
double
aXoffset
,
double
aYoffset
);
};
};
#endif // VRML_LAYER_H
#endif // VRML_LAYER_H
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