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
Show 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 @@
*/
/*
* 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 <kicad_string.h>
#include <wxPcbStruct.h>
...
...
@@ -88,7 +57,7 @@
#define MIN_VRML_LINEWIDTH 0.12
// offset for art layers, mm (silk, paste, etc)
#define ART_OFFSET 0.02
#define ART_OFFSET 0.02
5
/* helper function:
* some characters cannot be used in names,
...
...
@@ -183,6 +152,7 @@ public:
VRML_LAYER
bot_silk
;
VRML_LAYER
top_tin
;
VRML_LAYER
bot_tin
;
VRML_LAYER
plated_holes
;
double
scale
;
// board internal units to output scaling
double
minLineWidth
;
// minimum width of a VRML line segment
...
...
@@ -230,7 +200,17 @@ public:
void
SetOffset
(
double
aXoff
,
double
aYoff
)
{
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
)
...
...
@@ -278,6 +258,7 @@ public:
bot_silk
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
top_tin
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
bot_tin
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
plated_holes
.
SetArcParams
(
iMaxSeg
,
smin
,
smax
);
return
true
;
}
...
...
@@ -455,6 +436,16 @@ static void write_layers( MODEL_VRML& aModel, std::ofstream& output_file, BOARD*
-
Millimeter2iu
(
ART_OFFSET
/
2.0
)
*
aModel
.
scale
,
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;
aModel
.
top_silk
.
Tesselate
(
&
aModel
.
holes
);
write_triangle_bag
(
output_file
,
aModel
.
GetColor
(
VRML_COLOR_SILK
),
...
...
@@ -588,10 +579,10 @@ static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg )
{
LAYER_NUM
layer
=
drawseg
->
GetLayer
();
double
w
=
drawseg
->
GetWidth
()
*
aModel
.
scale
;
double
x
=
drawseg
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
y
=
drawseg
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
xf
=
drawseg
->
GetEnd
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
yf
=
drawseg
->
GetEnd
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
x
=
drawseg
->
GetStart
().
x
*
aModel
.
scale
;
double
y
=
drawseg
->
GetStart
().
y
*
aModel
.
scale
;
double
xf
=
drawseg
->
GetEnd
().
x
*
aModel
.
scale
;
double
yf
=
drawseg
->
GetEnd
().
y
*
aModel
.
scale
;
// Items on the edge layer are handled elsewhere; just return
if
(
layer
==
EDGE_N
)
...
...
@@ -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
;
int
s_text_width
=
model_vrml
->
s_text_width
;
double
scale
=
model_vrml
->
scale
;
double
tx
=
model_vrml
->
tx
;
double
ty
=
model_vrml
->
ty
;
export_vrml_line
(
*
model_vrml
,
s_text_layer
,
x0
*
scale
+
tx
,
y0
*
scale
+
ty
,
xf
*
scale
+
tx
,
yf
*
scale
+
ty
,
x0
*
scale
,
y0
*
scale
,
xf
*
scale
,
yf
*
scale
,
s_text_width
*
scale
);
}
...
...
@@ -729,8 +718,6 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
}
double
scale
=
aModel
.
scale
;
double
dx
=
aModel
.
tx
;
double
dy
=
aModel
.
ty
;
int
i
=
0
;
int
seg
;
...
...
@@ -756,8 +743,8 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
if
(
bufferPcbOutlines
[
i
].
end_contour
)
break
;
aModel
.
board
.
AddVertex
(
seg
,
bufferPcbOutlines
[
i
].
x
*
scale
+
dx
,
-
(
bufferPcbOutlines
[
i
].
y
*
scale
+
dy
)
);
aModel
.
board
.
AddVertex
(
seg
,
bufferPcbOutlines
[
i
].
x
*
scale
,
-
(
bufferPcbOutlines
[
i
].
y
*
scale
)
);
++
i
;
}
...
...
@@ -788,8 +775,8 @@ static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
if
(
allLayerHoles
[
i
].
end_contour
)
break
;
aModel
.
holes
.
AddVertex
(
seg
,
allLayerHoles
[
i
].
x
*
scale
+
dx
,
-
(
allLayerHoles
[
i
].
y
*
scale
+
dy
)
);
aModel
.
holes
.
AddVertex
(
seg
,
allLayerHoles
[
i
].
x
*
scale
,
-
(
allLayerHoles
[
i
].
y
*
scale
)
);
++
i
;
}
...
...
@@ -849,8 +836,8 @@ static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, const VIA* via )
hole
=
via
->
GetDrillValue
()
*
aModel
.
scale
/
2.0
;
r
=
via
->
GetWidth
()
*
aModel
.
scale
/
2.0
;
x
=
via
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
;
y
=
via
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
;
x
=
via
->
GetStart
().
x
*
aModel
.
scale
;
y
=
via
->
GetStart
().
y
*
aModel
.
scale
;
via
->
LayerPair
(
&
top_layer
,
&
bottom_layer
);
// do not render a buried via
...
...
@@ -873,10 +860,10 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb )
else
if
(
track
->
GetLayer
()
==
FIRST_COPPER_LAYER
||
track
->
GetLayer
()
==
LAST_COPPER_LAYER
)
export_vrml_line
(
aModel
,
track
->
GetLayer
(),
track
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
,
track
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
,
track
->
GetEnd
().
x
*
aModel
.
scale
+
aModel
.
tx
,
track
->
GetEnd
().
y
*
aModel
.
scale
+
aModel
.
ty
,
track
->
GetStart
().
x
*
aModel
.
scale
,
track
->
GetStart
().
y
*
aModel
.
scale
,
track
->
GetEnd
().
x
*
aModel
.
scale
,
track
->
GetEnd
().
y
*
aModel
.
scale
,
track
->
GetWidth
()
*
aModel
.
scale
);
}
}
...
...
@@ -886,9 +873,6 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
{
double
scale
=
aModel
.
scale
;
double
dx
=
aModel
.
tx
;
double
dy
=
aModel
.
ty
;
double
x
,
y
;
for
(
int
ii
=
0
;
ii
<
aPcb
->
GetAreaCount
();
ii
++
)
...
...
@@ -920,8 +904,8 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
while
(
i
<
nvert
)
{
x
=
poly
.
GetX
(
i
)
*
scale
+
dx
;
y
=
-
(
poly
.
GetY
(
i
)
*
scale
+
dy
);
x
=
poly
.
GetX
(
i
)
*
scale
;
y
=
-
(
poly
.
GetY
(
i
)
*
scale
);
if
(
poly
.
IsEndContour
(
i
)
)
break
;
...
...
@@ -971,10 +955,10 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
double
aOrientation
)
{
LAYER_NUM
layer
=
aOutline
->
GetLayer
();
double
x
=
aOutline
->
GetStart
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
y
=
aOutline
->
GetStart
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
xf
=
aOutline
->
GetEnd
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
yf
=
aOutline
->
GetEnd
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
x
=
aOutline
->
GetStart
().
x
*
aModel
.
scale
;
double
y
=
aOutline
->
GetStart
().
y
*
aModel
.
scale
;
double
xf
=
aOutline
->
GetEnd
().
x
*
aModel
.
scale
;
double
yf
=
aOutline
->
GetEnd
().
y
*
aModel
.
scale
;
double
w
=
aOutline
->
GetWidth
()
*
aModel
.
scale
;
switch
(
aOutline
->
GetShape
()
)
...
...
@@ -1015,8 +999,8 @@ static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
corner
.
x
+=
aOutline
->
GetPosition
().
x
;
corner
.
y
+=
aOutline
->
GetPosition
().
y
;
x
=
corner
.
x
*
aModel
.
scale
+
aModel
.
tx
;
y
=
-
(
corner
.
y
*
aModel
.
scale
+
aModel
.
ty
);
x
=
corner
.
x
*
aModel
.
scale
;
y
=
-
(
corner
.
y
*
aModel
.
scale
);
if
(
!
vl
->
AddVertex
(
seg
,
x
,
y
)
)
throw
(
std
::
runtime_error
(
vl
->
GetError
()
)
);
...
...
@@ -1037,8 +1021,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
{
// The (maybe offset) pad position
wxPoint
pad_pos
=
aPad
->
ShapePos
();
double
pad_x
=
pad_pos
.
x
*
aModel
.
scale
+
aModel
.
tx
;
double
pad_y
=
pad_pos
.
y
*
aModel
.
scale
+
aModel
.
ty
;
double
pad_x
=
pad_pos
.
x
*
aModel
.
scale
;
double
pad_y
=
pad_pos
.
y
*
aModel
.
scale
;
wxSize
pad_delta
=
aPad
->
GetDelta
();
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 )
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
=
std
::
min
(
hole_drill_w
,
hole_drill_h
);
double
hole_x
=
aPad
->
GetPosition
().
x
*
aModel
.
scale
+
aModel
.
tx
;
double
hole_y
=
aPad
->
GetPosition
().
y
*
aModel
.
scale
+
aModel
.
ty
;
double
hole_x
=
aPad
->
GetPosition
().
x
*
aModel
.
scale
;
double
hole_y
=
aPad
->
GetPosition
().
y
*
aModel
.
scale
;
// Export the hole on the edge layer
if
(
hole_drill
>
0
)
{
bool
pth
=
false
;
if
(
aPad
->
GetAttribute
()
!=
PAD_HOLE_NOT_PLATED
)
pth
=
true
;
if
(
aPad
->
GetDrillShape
()
==
PAD_DRILL_OBLONG
)
{
// Oblong hole (slot)
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
{
// 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,
EDA_RECT
bbbox
=
pcb
->
ComputeBoundingBox
();
model3d
.
SetOffset
(
-
model3d
.
scale
*
bbbox
.
Centre
().
x
,
-
model3d
.
scale
*
bbbox
.
Centre
().
y
);
model3d
.
scale
*
bbbox
.
Centre
().
y
);
output_file
<<
" children [
\n
"
;
...
...
utils/idftools/vrml_layer.cpp
View file @
a91eabb8
...
...
@@ -23,6 +23,14 @@
* 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 <string>
#include <iomanip>
...
...
@@ -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
)
{
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()
maxArcSeg
=
48
;
minSegLength
=
0.1
;
maxSegLength
=
0.5
;
offsetX
=
0.0
;
offsetY
=
0.0
;
fix
=
false
;
Fault
=
false
;
...
...
@@ -230,6 +252,8 @@ void VRML_LAYER::Clear( void )
contours
.
pop_back
();
}
pth
.
clear
();
areas
.
clear
();
for
(
i
=
vertices
.
size
();
i
>
0
;
--
i
)
...
...
@@ -254,6 +278,7 @@ void VRML_LAYER::clearTmp( void )
glcmd
=
0
;
triplets
.
clear
();
solid
.
clear
();
for
(
i
=
outline
.
size
();
i
>
0
;
--
i
)
{
...
...
@@ -283,7 +308,7 @@ void VRML_LAYER::clearTmp( void )
// create a new contour to be populated; returns an index
// into the contour list or -1 if there are problems
int
VRML_LAYER
::
NewContour
(
void
)
int
VRML_LAYER
::
NewContour
(
bool
aPlatedHole
)
{
if
(
fix
)
return
-
1
;
...
...
@@ -296,6 +321,8 @@ int VRML_LAYER::NewContour( void )
contours
.
push_back
(
contour
);
areas
.
push_back
(
0.0
);
pth
.
push_back
(
aPlatedHole
);
return
contours
.
size
()
-
1
;
}
...
...
@@ -329,6 +356,7 @@ bool VRML_LAYER::AddVertex( int aContourID, double aXpos, double aYpos )
vertex
->
y
=
aYpos
;
vertex
->
i
=
idx
++
;
vertex
->
o
=
-
1
;
vertex
->
pth
=
pth
[
aContourID
];
VERTEX_3D
*
v2
=
NULL
;
...
...
@@ -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
// 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
)
{
...
...
@@ -458,7 +492,7 @@ bool VRML_LAYER::AddCircle( double aXpos, double aYpos, double aRadius, bool aHo
// contour is a hole. Returns true if OK.
bool
VRML_LAYER
::
AddSlot
(
double
aCenterX
,
double
aCenterY
,
double
aSlotLength
,
double
aSlotWidth
,
double
aAngle
,
bool
aHoleFlag
)
double
aAngle
,
bool
aHoleFlag
,
bool
aPlatedHole
)
{
aAngle
*=
M_PI
/
180.0
;
...
...
@@ -480,7 +514,12 @@ bool VRML_LAYER::AddSlot( double aCenterX, double aCenterY,
double
ang
,
da
;
int
i
;
int
pad
=
NewContour
();
int
pad
;
if
(
aHoleFlag
&&
aPlatedHole
)
pad
=
NewContour
(
true
);
else
pad
=
NewContour
(
false
);
if
(
pad
<
0
)
{
...
...
@@ -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).
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
;
...
...
@@ -636,7 +675,12 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
std
::
swap
(
iendy
,
isty
);
}
int
arc
=
NewContour
();
int
arc
;
if
(
aHoleFlag
&&
aPlatedHole
)
arc
=
NewContour
(
true
);
else
arc
=
NewContour
(
false
);
if
(
arc
<
0
)
{
...
...
@@ -688,7 +732,7 @@ bool VRML_LAYER::AddArc( double aCenterX, double aCenterY, double aStartX, doubl
// tesselates the contours in preparation for a 3D output;
// 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
)
{
...
...
@@ -699,6 +743,12 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
pholes
=
holes
;
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
)
{
error
=
"Tesselate(): not enough vertices"
;
...
...
@@ -736,9 +786,37 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
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
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
pushVertices
(
false
);
...
...
@@ -748,6 +826,13 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
if
(
Fault
)
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
gluTessBeginPolygon
(
tess
,
this
);
...
...
@@ -793,6 +878,7 @@ bool VRML_LAYER::Tesselate( VRML_LAYER* holes )
// close the polygon; this creates the outline points
// and the point ordering list 'ordmap'
solid
.
clear
();
gluTessEndPolygon
(
tess
);
// repeat the last operation but request a tesselated surface
...
...
@@ -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
oend
=
outline
.
end
();
int
nc
=
0
;
// number of contours pushed
int
pi
;
std
::
list
<
int
>::
const_iterator
begin
;
std
::
list
<
int
>::
const_iterator
end
;
...
...
@@ -876,6 +964,13 @@ bool VRML_LAYER::pushOutline( VRML_LAYER* holes )
gluTessEndContour
(
tess
);
++
obeg
;
++
nc
;
}
if
(
!
nc
)
{
error
=
"pushOutline():: no valid contours available"
;
return
false
;
}
return
true
;
...
...
@@ -902,7 +997,7 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPr
return
false
;
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
);
aOutFile
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
...
@@ -914,7 +1009,7 @@ bool VRML_LAYER::WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPr
if
(
!
vp
)
return
false
;
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
if
(
i
&
1
)
aOutFile
<<
", "
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
...
@@ -954,7 +1049,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
return
false
;
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
);
aOutFile
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
...
@@ -966,7 +1061,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
if
(
!
vp
)
return
false
;
FormatDoublet
(
vp
->
x
,
vp
->
y
,
aPrecision
,
strx
,
stry
);
FormatDoublet
(
vp
->
x
+
offsetX
,
vp
->
y
+
offsetY
,
aPrecision
,
strx
,
stry
);
if
(
i
&
1
)
aOutFile
<<
", "
<<
strx
<<
" "
<<
stry
<<
" "
<<
strz
;
...
...
@@ -976,7 +1071,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
// repeat for the bottom layer
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
);
bool
endl
;
...
...
@@ -995,7 +1090,7 @@ bool VRML_LAYER::Write3DVertices( double aTopZ, double aBottomZ,
for
(
i
=
1
,
j
=
ordmap
.
size
();
i
<
j
;
++
i
)
{
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
)
{
...
...
@@ -1064,27 +1159,28 @@ bool VRML_LAYER::WriteIndices( bool aTopFlag, std::ofstream& aOutFile )
// 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
()
)
{
error
=
"WriteIndices(): no outline available"
;
return
false
;
}
// 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
();
char
mark
;
bool
holes_only
=
triplets
.
empty
();
int
i
=
1
;
int
idx2
=
ordmap
.
size
();
// index to the bottom vertices
if
(
!
holes_only
)
{
mark
=
','
;
// 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 top vertices
aOutFile
<<
tbeg
->
i1
<<
", "
<<
tbeg
->
i2
<<
", "
<<
tbeg
->
i3
<<
", -1"
;
++
tbeg
;
...
...
@@ -1121,11 +1217,15 @@ bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile )
++
tbeg
;
}
}
else
mark
=
' '
;
// print out indices for the walls joining top to bottom
int
firstPoint
;
int
lastPoint
;
int
curPoint
;
int
curContour
=
0
;
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
obeg
=
outline
.
begin
();
std
::
list
<
std
::
list
<
int
>*>::
const_iterator
oend
=
outline
.
end
();
...
...
@@ -1141,45 +1241,96 @@ bool VRML_LAYER::Write3DIndices( std::ofstream& aOutFile )
if
(
cp
->
size
()
<
3
)
{
++
obeg
;
++
curContour
;
continue
;
}
cbeg
=
cp
->
begin
();
cend
=
cp
->
end
();
lastPoint
=
*
(
cbeg
++
);
firstPoint
=
*
(
cbeg
++
);
lastPoint
=
firstPoint
;
// skip all PTH vertices which are not in a solid outline
if
(
!
aIncludePlatedHoles
&&
!
solid
[
curContour
]
&&
getVertexByIndex
(
ordmap
[
lastPoint
],
pholes
)
->
pth
)
{
++
obeg
;
++
curContour
;
continue
;
}
while
(
cbeg
!=
cend
)
{
curPoint
=
*
(
cbeg
++
);
if
(
!
holes_only
)
{
if
(
(
i
++
&
3
)
==
2
)
{
i
=
1
;
aOutFile
<<
",
\n
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
mark
<<
"
\n
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
else
{
aOutFile
<<
",
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
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
)
{
aOutFile
<<
",
\n
"
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
else
{
aOutFile
<<
", "
<<
curPoint
<<
", "
<<
lastPoint
<<
", "
<<
curPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
}
}
else
{
if
(
(
i
++
&
3
)
==
2
)
{
aOutFile
<<
",
\n
"
<<
firstPoint
<<
", "
<<
lastPoint
<<
", "
<<
firstPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
firstPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
aOutFile
<<
",
\n
"
<<
curPoint
<<
", "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
+
idx2
<<
", "
<<
lastPoint
<<
", -1"
;
}
else
{
aOutFile
<<
", "
<<
firstPoint
<<
", "
<<
lastPoint
<<
", "
<<
firstPoint
+
idx2
;
aOutFile
<<
", -1, "
<<
firstPoint
+
idx2
<<
", "
<<
lastPoint
<<
", "
<<
lastPoint
+
idx2
<<
", -1"
;
aOutFile
<<
", "
<<
curPoint
<<
", "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
;
aOutFile
<<
", -1, "
<<
curPoint
+
idx2
<<
", "
<<
lastPoint
+
idx2
<<
", "
<<
lastPoint
<<
", -1"
;
}
}
++
obeg
;
++
curContour
;
}
return
!
aOutFile
.
fail
();
...
...
@@ -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)
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
;
...
...
@@ -1239,6 +1390,7 @@ VERTEX_3D* VRML_LAYER::AddExtraVertex( double aXpos, double aYpos )
vertex
->
y
=
aYpos
;
vertex
->
i
=
eidx
++
;
vertex
->
o
=
-
1
;
vertex
->
pth
=
aPlatedHole
;
extra_verts
.
push_back
(
vertex
);
...
...
@@ -1282,12 +1434,39 @@ void VRML_LAYER::glEnd( void )
if
(
!
loop
)
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
);
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
);
if
(
area
<=
0.0
)
solid
.
push_back
(
true
);
else
solid
.
push_back
(
false
);
}
break
;
...
...
@@ -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
void
VRML_LAYER
::
pushVertices
(
bool
holes
)
{
...
...
@@ -1434,6 +1638,8 @@ void VRML_LAYER::pushVertices( bool holes )
gluTessEndContour
(
tess
);
}
return
;
}
...
...
@@ -1564,3 +1770,11 @@ const std::string& VRML_LAYER::GetError( void )
{
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
double
y
;
int
i
;
// vertex index
int
o
;
// vertex order
bool
pth
;
// true for plate-through hole
};
struct
TRIPLET_3D
...
...
@@ -93,12 +94,18 @@ private:
double
minSegLength
;
// min. 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
int
idx
;
// vertex index (number of contained vertices)
int
ord
;
// vertex order (number of ordered vertices)
unsigned
int
idxout
;
// outline index to first point in 3D outline
std
::
vector
<
VERTEX_3D
*>
vertices
;
// vertices of all contours
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
::
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)
...
...
@@ -136,6 +143,9 @@ private:
// calculate number of sides on an arc (angle is in radians)
int
calcNSides
(
double
aRadius
,
double
aAngle
);
// returns the number of solid or hole contours
int
checkNContours
(
bool
holes
);
public
:
/// set to true when a fault is encountered during tesselation
bool
Fault
;
...
...
@@ -191,9 +201,11 @@ public:
* Function NewContour
* 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
*/
int
NewContour
(
void
);
int
NewContour
(
bool
aPlatedHole
=
false
);
/**
* Function AddVertex
...
...
@@ -231,7 +243,8 @@ public:
*
* @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
...
...
@@ -241,10 +254,12 @@ public:
* @param aYpos is the Y coordinate of the hole center
* @param aRadius is the radius of the hole
* @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
*/
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
...
...
@@ -256,11 +271,12 @@ public:
* @param aSlotWidth is the width of the slot along the minor axis
* @param aAngle (degrees) is the orientation of the slot
* @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
*/
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
...
...
@@ -289,11 +305,14 @@ public:
* @param aArcWidth is the width of the arc
* @param aAngle is the included angle (degrees)
* @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
*/
bool
AddArc
(
double
aCenterX
,
double
aCenterY
,
double
aStartX
,
double
aStartY
,
double
aArcWidth
,
double
aAngle
,
bool
aHoleFlag
=
false
);
bool
AddArc
(
double
aCenterX
,
double
aCenterY
,
double
aStartX
,
double
aStartY
,
double
aArcWidth
,
double
aAngle
,
bool
aHoleFlag
=
false
,
bool
aPlatedHole
=
false
);
/**
* Function Tesselate
...
...
@@ -302,10 +321,11 @@ public:
*
* @param holes is an optional pointer to cutouts to be imposed on the
* surface.
* @param aHolesOnly is true if the outline contains only holes
*
* @return bool: true if the operation succeeded
*/
bool
Tesselate
(
VRML_LAYER
*
holes
=
NULL
);
bool
Tesselate
(
VRML_LAYER
*
holes
=
NULL
,
bool
aHolesOnly
=
false
);
/**
* Function WriteVertices
...
...
@@ -351,19 +371,26 @@ public:
* writes out the vertex sets required to render an extruded solid
*
* @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
*/
bool
Write3DIndices
(
std
::
ofstream
&
aOutFile
);
bool
Write3DIndices
(
std
::
ofstream
&
aOutFile
,
bool
aIncludePlatedHoles
=
false
);
/**
* 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
* could not be created.
*/
VERTEX_3D
*
AddExtraVertex
(
double
aXpos
,
double
aYpos
);
VERTEX_3D
*
AddExtraVertex
(
double
aXpos
,
double
aYpos
,
bool
aPlatedHole
);
/**
* Function glStart
...
...
@@ -429,6 +456,8 @@ public:
* Returns the error message related to the last failed operation
*/
const
std
::
string
&
GetError
(
void
);
void
SetVertexOffsets
(
double
aXoffset
,
double
aYoffset
);
};
#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