Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Benjamin Jakimow
EO Time Series Viewer
Commits
d2d812c8
Commit
d2d812c8
authored
Mar 24, 2012
by
Luke Campagnola
Browse files
Fixed up MeshData and GLMeshItem classes for surface display
parent
f6da6e2f
Changes
2
Hide whitespace changes
Inline
Side-by-side
opengl/MeshData.py
View file @
d2d812c8
from
pyqtgraph.Qt
import
QtGui
class
MeshData
(
object
):
"""
Class for storing 3D mesh data. May contain:
...
...
@@ -9,15 +11,16 @@ class MeshData(object):
"""
def
__init__
(
self
):
self
.
vertexes
=
[]
self
.
edges
=
None
self
.
faces
=
[]
self
.
vertexFaces
=
None
## maps vertex ID to a list of face IDs
self
.
vertexNormals
=
None
self
.
faceNormals
=
None
self
.
vertexColors
=
None
self
.
edgeColors
=
None
self
.
faceColors
=
None
self
.
_vertexes
=
[]
self
.
_edges
=
None
self
.
_faces
=
[]
self
.
_vertexFaces
=
None
## maps vertex ID to a list of face IDs
self
.
_vertexNormals
=
None
self
.
_faceNormals
=
None
self
.
_vertexColors
=
None
self
.
_edgeColors
=
None
self
.
_faceColors
=
None
self
.
_meshColor
=
(
1
,
1
,
1
,
0.1
)
# default color to use if no face/edge/vertex colors are given
def
setFaces
(
self
,
faces
,
vertexes
=
None
):
"""
...
...
@@ -30,84 +33,111 @@ class MeshData(object):
"""
if
vertexes
is
None
:
self
.
_setUnindexedFaces
(
self
,
faces
)
self
.
_setUnindexedFaces
(
faces
)
else
:
self
.
_setIndexedFaces
(
self
,
faces
)
self
.
_setIndexedFaces
(
faces
,
vertexes
)
def
_setUnindexedFaces
(
self
,
faces
):
verts
=
{}
self
.
faces
=
[]
self
.
vertexes
=
[]
self
.
vertexFaces
=
[]
self
.
faceNormals
=
None
self
.
vertexNormals
=
None
self
.
_
faces
=
[]
self
.
_
vertexes
=
[]
self
.
_
vertexFaces
=
[]
self
.
_
faceNormals
=
None
self
.
_
vertexNormals
=
None
for
face
in
faces
:
inds
=
[]
for
pt
in
face
:
pt2
=
tuple
([
int
(
x
*
1e14
)
for
x
in
pt
])
## quantize to be sure that nearly-identical points will be merged
pt2
=
tuple
([
round
(
x
*
1e14
)
for
x
in
pt
])
## quantize to be sure that nearly-identical points will be merged
index
=
verts
.
get
(
pt2
,
None
)
if
index
is
None
:
self
.
vertexes
.
append
(
tuple
(
pt
))
self
.
vertexFaces
.
append
([])
index
=
len
(
self
.
vertexes
)
-
1
self
.
_
vertexes
.
append
(
QtGui
.
QVector3D
(
*
pt
))
self
.
_
vertexFaces
.
append
([])
index
=
len
(
self
.
_
vertexes
)
-
1
verts
[
pt2
]
=
index
self
.
vertexFaces
[
index
].
append
(
face
)
self
.
_
vertexFaces
[
index
].
append
(
len
(
self
.
_
face
s
)
)
inds
.
append
(
index
)
self
.
faces
.
append
(
tuple
(
inds
))
self
.
_
faces
.
append
(
tuple
(
inds
))
def
_setIndexedFaces
(
self
,
faces
,
vertexes
):
self
.
vertexes
=
vertexes
self
.
faces
=
faces
self
.
edges
=
None
self
.
vertexFaces
=
None
self
.
faceNormals
=
None
self
.
vertexNormals
=
None
self
.
_
vertexes
=
[
QtGui
.
QVector3D
(
*
v
)
for
v
in
vertexes
]
self
.
_
faces
=
faces
self
.
_
edges
=
None
self
.
_
vertexFaces
=
None
self
.
_
faceNormals
=
None
self
.
_
vertexNormals
=
None
def
getV
ertexFaces
(
self
):
def
v
ertexFaces
(
self
):
"""
Return list mapping each vertex index to a list of face indexes that use the vertex.
"""
if
self
.
vertexFaces
is
None
:
self
.
vertexFaces
=
[[]]
*
len
(
self
.
vertexes
)
for
i
,
face
in
enumerate
(
self
.
faces
):
if
self
.
_
vertexFaces
is
None
:
self
.
_
vertexFaces
=
[[]]
*
len
(
self
.
_
vertexes
)
for
i
,
face
in
enumerate
(
self
.
_
faces
):
for
ind
in
face
:
if
len
(
self
.
vertexFaces
[
ind
])
==
0
:
self
.
vertexFaces
[
ind
]
=
[]
## need a unique/empty list to fill
self
.
vertexFaces
[
ind
].
append
(
i
)
return
self
.
vertexFaces
if
len
(
self
.
_
vertexFaces
[
ind
])
==
0
:
self
.
_
vertexFaces
[
ind
]
=
[]
## need a unique/empty list to fill
self
.
_
vertexFaces
[
ind
].
append
(
i
)
return
self
.
_
vertexFaces
def
getFaceNormals
(
self
):
def
__iter__
(
self
):
"""Iterate over all faces, yielding a list of three tuples [(position, normal, color), ...] for each face."""
vnorms
=
self
.
vertexNormals
()
vcolors
=
self
.
vertexColors
()
for
i
in
range
(
len
(
self
.
_faces
)):
face
=
[]
for
j
in
[
0
,
1
,
2
]:
vind
=
self
.
_faces
[
i
][
j
]
pos
=
self
.
_vertexes
[
vind
]
norm
=
vnorms
[
vind
]
if
vcolors
is
None
:
color
=
self
.
_meshColor
else
:
color
=
vcolors
[
vind
]
face
.
append
((
pos
,
norm
,
color
))
yield
face
def
faceNormals
(
self
):
"""
Computes and stores normal of each face.
"""
if
self
.
faceNormals
is
None
:
self
.
faceNormals
=
[]
for
i
,
face
in
enumerate
(
self
.
faces
):
if
self
.
_
faceNormals
is
None
:
self
.
_
faceNormals
=
[]
for
i
,
face
in
enumerate
(
self
.
_
faces
):
## compute face normal
pts
=
[
QtGui
.
QVector3D
(
*
self
.
vertexes
[
vind
]
)
for
vind
in
face
]
norm
=
QtGui
.
QVector3D
.
crossProduct
(
pts
[
1
]
-
pts
[
0
],
pts
[
2
]
-
pts
[
0
])
self
.
faceNormals
.
append
(
norm
)
return
self
.
faceNormals
pts
=
[
self
.
_
vertexes
[
vind
]
for
vind
in
face
]
norm
=
QtGui
.
QVector3D
.
crossProduct
(
pts
[
1
]
-
pts
[
0
],
pts
[
2
]
-
pts
[
0
])
.
normalized
()
self
.
_
faceNormals
.
append
(
norm
)
return
self
.
_
faceNormals
def
getV
ertexNormals
(
self
):
def
v
ertexNormals
(
self
):
"""
Assigns each vertex the average of its connected face normals.
If face normals have not been computed yet, then generateFaceNormals will be called.
"""
if
self
.
vertexNormals
is
None
:
faceNorms
=
self
.
getFaceNormals
()
vertFaces
=
self
.
getVertexFaces
()
self
.
vertexNormals
=
[]
for
vindex
in
xrange
(
len
(
self
.
vertexes
)):
if
self
.
_vertexNormals
is
None
:
faceNorms
=
self
.
faceNormals
()
vertFaces
=
self
.
vertexFaces
()
self
.
_vertexNormals
=
[]
for
vindex
in
xrange
(
len
(
self
.
_vertexes
)):
#print vertFaces[vindex]
norms
=
[
faceNorms
[
findex
]
for
findex
in
vertFaces
[
vindex
]]
if
len
(
norms
)
==
0
:
norm
=
QtGui
.
QVector3D
()
else
:
norm
=
reduce
(
QtGui
.
QVector3D
.
__add__
,
facenorms
)
/
float
(
len
(
norms
))
self
.
vertexNormals
.
append
(
norm
)
return
self
.
vertexNormals
norm
=
QtGui
.
QVector3D
()
for
fn
in
norms
:
norm
+=
fn
norm
.
normalize
()
self
.
_vertexNormals
.
append
(
norm
)
return
self
.
_vertexNormals
def
vertexColors
(
self
):
return
self
.
_vertexColors
def
faceColors
(
self
):
return
self
.
_faceColors
def
edgeColors
(
self
):
return
self
.
_edgeColors
def
reverseNormals
(
self
):
"""
...
...
opengl/items/GLMeshItem.py
View file @
d2d812c8
from
OpenGL.GL
import
*
from
..
GLGraphicsItem
import
GLGraphicsItem
from
..
MeshData
import
MeshData
from
pyqtgraph.Qt
import
QtGui
import
pyqtgraph
as
pg
from
..
import
shaders
...
...
@@ -10,33 +11,20 @@ import numpy as np
__all__
=
[
'GLMeshItem'
]
class
GLMeshItem
(
GLGraphicsItem
):
def
__init__
(
self
,
faces
):
self
.
faces
=
faces
self
.
normals
,
self
.
faceNormals
=
pg
.
meshNormals
(
faces
)
"""
Displays a 3D triangle mesh.
"""
def
__init__
(
self
,
faces
,
vertexes
=
None
):
"""
See MeshData for initialization arguments.
"""
self
.
data
=
MeshData
()
self
.
data
.
setFaces
(
faces
,
vertexes
)
GLGraphicsItem
.
__init__
(
self
)
def
initializeGL
(
self
):
#balloonVertexShader = shaders.compileShader("""
#varying vec3 normal;
#void main() {
#normal = normalize(gl_NormalMatrix * gl_Normal);
#//vec4 color = normal;
#//normal.w = min(color.w + 2.0 * color.w * pow(normal.x*normal.x + normal.y*normal.y, 2.0), 1.0);
#gl_FrontColor = gl_Color;
#gl_BackColor = gl_Color;
#gl_Position = ftransform();
#}""", GL_VERTEX_SHADER)
#balloonFragmentShader = shaders.compileShader("""
#varying vec3 normal;
#void main() {
#vec4 color = gl_Color;
#color.w = min(color.w + 2.0 * color.w * pow(normal.x*normal.x + normal.y*normal.y, 5.0), 1.0);
#gl_FragColor = color;
#}""", GL_FRAGMENT_SHADER)
#self.shader = shaders.compileProgram(balloonVertexShader, balloonFragmentShader)
self
.
shader
=
shaders
.
getShader
(
'balloon'
)
l
=
glGenLists
(
1
)
...
...
@@ -51,39 +39,33 @@ class GLMeshItem(GLGraphicsItem):
glDisable
(
GL_DEPTH_TEST
)
glColor4f
(
1
,
1
,
1
,
.
1
)
glBegin
(
GL_TRIANGLES
)
for
i
,
f
in
enumerate
(
self
.
faces
):
pts
=
[
QtGui
.
QVector3D
(
*
x
)
for
x
in
f
]
if
pts
[
0
]
is
None
:
print
f
continue
#norm = QtGui.QVector3D.crossProduct(pts[1]-pts[0], pts[2]-pts[0])
for
j
in
[
0
,
1
,
2
]:
norm
=
self
.
normals
[
self
.
faceNormals
[
i
][
j
]]
for
face
in
self
.
data
:
for
(
pos
,
norm
,
color
)
in
face
:
glColor4f
(
*
color
)
glNormal3f
(
norm
.
x
(),
norm
.
y
(),
norm
.
z
())
#j = (i+1) % 3
glVertex3f
(
*
f
[
j
])
glVertex3f
(
pos
.
x
(),
pos
.
y
(),
pos
.
z
())
glEnd
()
glEndList
()
l
=
glGenLists
(
1
)
self
.
meshList
=
l
glNewList
(
l
,
GL_COMPILE
)
glBlendFunc
(
GL_SRC_ALPHA
,
GL_ONE_MINUS_SRC_ALPHA
)
glEnable
(
GL_BLEND
)
glEnable
(
GL_ALPHA_TEST
)
#glAlphaFunc( GL_ALWAYS,0.5 )
glEnable
(
GL_POINT_SMOOTH
)
glEnable
(
GL_DEPTH_TEST
)
glColor4f
(
1
,
1
,
1
,
.
3
)
glBegin
(
GL_LINES
)
for
f
in
self
.
faces
:
for
i
in
[
0
,
1
,
2
]:
j
=
(
i
+
1
)
%
3
glVertex3f
(
*
f
[
i
])
glVertex3f
(
*
f
[
j
])
glEnd
()
glEndList
()
#
l = glGenLists(1)
#
self.meshList = l
#
glNewList(l, GL_COMPILE)
#
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
#
glEnable( GL_BLEND )
#
glEnable( GL_ALPHA_TEST )
#
#glAlphaFunc( GL_ALWAYS,0.5 )
#
glEnable( GL_POINT_SMOOTH )
#
glEnable( GL_DEPTH_TEST )
#
glColor4f(1, 1, 1, .3)
#
glBegin( GL_LINES )
#
for f in self.faces:
#
for i in [0,1,2]:
#
j = (i+1) % 3
#
glVertex3f(*f[i])
#
glVertex3f(*f[j])
#
glEnd()
#
glEndList()
def
paint
(
self
):
...
...
Write
Preview
Supports
Markdown
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