Added basic wireframe mesh drawing
This commit is contained in:
parent
af4980d153
commit
ba56899a36
@ -83,6 +83,16 @@ m3 = gl.GLMeshItem(meshdata=md, smooth=False)#, shader='balloon')
|
||||
w.addItem(m3)
|
||||
|
||||
|
||||
# Example 4:
|
||||
# wireframe
|
||||
|
||||
md = gl.MeshData.sphere(rows=4, cols=8)
|
||||
m4 = gl.GLMeshItem(meshdata=md, smooth=False, drawFaces=False, drawEdges=True, edgeColor=(1,1,1,1))
|
||||
m4.translate(0,10,0)
|
||||
w.addItem(m4)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@ class MeshData(object):
|
||||
|
||||
## mappings between vertexes, faces, and edges
|
||||
self._faces = None # Nx3 array of indexes into self._vertexes specifying three vertexes for each face
|
||||
self._edges = None
|
||||
self._edges = None # Nx2 array of indexes into self._vertexes specifying two vertexes per edge
|
||||
self._vertexFaces = None ## maps vertex ID to a list of face IDs (inverse mapping of _faces)
|
||||
self._vertexEdges = None ## maps vertex ID to a list of edge IDs (inverse mapping of _edges)
|
||||
|
||||
@ -143,12 +143,19 @@ class MeshData(object):
|
||||
def faces(self):
|
||||
"""Return an array (Nf, 3) of vertex indexes, three per triangular face in the mesh."""
|
||||
return self._faces
|
||||
|
||||
def edges(self):
|
||||
"""Return an array (Nf, 3) of vertex indexes, two per edge in the mesh."""
|
||||
if self._edges is None:
|
||||
self._computeEdges()
|
||||
return self._edges
|
||||
|
||||
def setFaces(self, faces):
|
||||
"""Set the (Nf, 3) array of faces. Each rown in the array contains
|
||||
three indexes into the vertex array, specifying the three corners
|
||||
of a triangular face."""
|
||||
self._faces = faces
|
||||
self._edges = None
|
||||
self._vertexFaces = None
|
||||
self._vertexesIndexedByFaces = None
|
||||
self.resetNormals()
|
||||
@ -418,6 +425,25 @@ class MeshData(object):
|
||||
#"""
|
||||
#pass
|
||||
|
||||
def _computeEdges(self):
|
||||
## generate self._edges from self._faces
|
||||
#print self._faces
|
||||
nf = len(self._faces)
|
||||
edges = np.empty(nf*3, dtype=[('i', np.uint, 2)])
|
||||
edges['i'][0:nf] = self._faces[:,:2]
|
||||
edges['i'][nf:2*nf] = self._faces[:,1:3]
|
||||
edges['i'][-nf:,0] = self._faces[:,2]
|
||||
edges['i'][-nf:,1] = self._faces[:,0]
|
||||
|
||||
# sort per-edge
|
||||
mask = edges['i'][:,0] > edges['i'][:,1]
|
||||
edges['i'][mask] = edges['i'][mask][:,::-1]
|
||||
|
||||
# remove duplicate entries
|
||||
self._edges = np.unique(edges)['i']
|
||||
#print self._edges
|
||||
|
||||
|
||||
def save(self):
|
||||
"""Serialize this mesh to a string appropriate for disk storage"""
|
||||
import pickle
|
||||
|
@ -22,9 +22,15 @@ class GLMeshItem(GLGraphicsItem):
|
||||
Arguments
|
||||
meshdata MeshData object from which to determine geometry for
|
||||
this item.
|
||||
color Default color used if no vertex or face colors are
|
||||
specified.
|
||||
shader Name of shader program to use (None for no shader)
|
||||
color Default face color used if no vertex or face colors
|
||||
are specified.
|
||||
edgeColor Default edge color to use if no edge colors are
|
||||
specified in the mesh data.
|
||||
drawEdges If True, a wireframe mesh will be drawn.
|
||||
(default=False)
|
||||
drawFaces If True, mesh faces are drawn. (default=True)
|
||||
shader Name of shader program to use when drawing faces.
|
||||
(None for no shader)
|
||||
smooth If True, normal vectors are computed for each vertex
|
||||
and interpolated within each face.
|
||||
computeNormals If False, then computation of normal vectors is
|
||||
@ -35,6 +41,9 @@ class GLMeshItem(GLGraphicsItem):
|
||||
self.opts = {
|
||||
'meshdata': None,
|
||||
'color': (1., 1., 1., 1.),
|
||||
'drawEdges': False,
|
||||
'drawFaces': True,
|
||||
'edgeColor': (0.5, 0.5, 0.5, 1.0),
|
||||
'shader': None,
|
||||
'smooth': True,
|
||||
'computeNormals': True,
|
||||
@ -100,6 +109,8 @@ class GLMeshItem(GLGraphicsItem):
|
||||
self.faces = None
|
||||
self.normals = None
|
||||
self.colors = None
|
||||
self.edges = None
|
||||
self.edgeColors = None
|
||||
self.update()
|
||||
|
||||
def parseMeshData(self):
|
||||
@ -137,6 +148,9 @@ class GLMeshItem(GLGraphicsItem):
|
||||
elif md.hasFaceColor():
|
||||
self.colors = md.faceColors(indexed='faces')
|
||||
|
||||
if self.opts['drawEdges']:
|
||||
self.edges = md.edges()
|
||||
self.edgeVerts = md.vertexes()
|
||||
return
|
||||
|
||||
def paint(self):
|
||||
@ -144,19 +158,52 @@ class GLMeshItem(GLGraphicsItem):
|
||||
|
||||
self.parseMeshData()
|
||||
|
||||
with self.shader():
|
||||
verts = self.vertexes
|
||||
norms = self.normals
|
||||
color = self.colors
|
||||
faces = self.faces
|
||||
if verts is None:
|
||||
return
|
||||
if self.opts['drawFaces']:
|
||||
with self.shader():
|
||||
verts = self.vertexes
|
||||
norms = self.normals
|
||||
color = self.colors
|
||||
faces = self.faces
|
||||
if verts is None:
|
||||
return
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
try:
|
||||
glVertexPointerf(verts)
|
||||
|
||||
if self.colors is None:
|
||||
color = self.opts['color']
|
||||
if isinstance(color, QtGui.QColor):
|
||||
glColor4f(*pg.glColor(color))
|
||||
else:
|
||||
glColor4f(*color)
|
||||
else:
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
glColorPointerf(color)
|
||||
|
||||
|
||||
if norms is not None:
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
glNormalPointerf(norms)
|
||||
|
||||
if faces is None:
|
||||
glDrawArrays(GL_TRIANGLES, 0, np.product(verts.shape[:-1]))
|
||||
else:
|
||||
faces = faces.astype(np.uint).flatten()
|
||||
glDrawElements(GL_TRIANGLES, faces.shape[0], GL_UNSIGNED_INT, faces)
|
||||
finally:
|
||||
glDisableClientState(GL_NORMAL_ARRAY)
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_COLOR_ARRAY)
|
||||
|
||||
if self.opts['drawEdges']:
|
||||
verts = self.edgeVerts
|
||||
edges = self.edges
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
try:
|
||||
glVertexPointerf(verts)
|
||||
|
||||
if self.colors is None:
|
||||
color = self.opts['color']
|
||||
if self.edgeColors is None:
|
||||
color = self.opts['edgeColor']
|
||||
if isinstance(color, QtGui.QColor):
|
||||
glColor4f(*pg.glColor(color))
|
||||
else:
|
||||
@ -164,19 +211,9 @@ class GLMeshItem(GLGraphicsItem):
|
||||
else:
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
glColorPointerf(color)
|
||||
|
||||
|
||||
if norms is not None:
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
glNormalPointerf(norms)
|
||||
|
||||
if faces is None:
|
||||
glDrawArrays(GL_TRIANGLES, 0, np.product(verts.shape[:-1]))
|
||||
else:
|
||||
faces = faces.astype(np.uint).flatten()
|
||||
glDrawElements(GL_TRIANGLES, faces.shape[0], GL_UNSIGNED_INT, faces)
|
||||
edges = edges.flatten()
|
||||
glDrawElements(GL_LINES, edges.shape[0], GL_UNSIGNED_INT, edges)
|
||||
finally:
|
||||
glDisableClientState(GL_NORMAL_ARRAY)
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_COLOR_ARRAY)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user