diff --git a/documentation/source/3dgraphics.rst b/documentation/source/3dgraphics.rst new file mode 100644 index 00000000..effa288d --- /dev/null +++ b/documentation/source/3dgraphics.rst @@ -0,0 +1,48 @@ +3D Graphics +=========== + +Pyqtgraph uses OpenGL to provide a 3D scenegraph system. This system is functional but still early in development. +Current capabilities include: + +* 3D view widget with zoom/rotate controls (mouse drag and wheel) +* Scenegraph allowing items to be added/removed from scene with per-item transformations and parent/child relationships. +* Triangular meshes +* Basic mesh computation functions: isosurfaces, per-vertex normals +* Volumetric rendering item +* Grid/axis items + +See the :doc:`API Reference ` and the Volumetric (GLVolumeItem.py) and Isosurface (GLMeshItem.py) examples for more information. + +Basic usage example:: + + ## build a QApplication before building other widgets + import pyqtgraph as pg + pg.mkQApp() + + ## make a widget for displaying 3D objects + import pyqtgraph.opengl as gl + view = gl.GLViewWidget() + view.show() + + ## create three grids, add each to the view + xgrid = gl.GLGridItem() + ygrid = gl.GLGridItem() + zgrid = gl.GLGridItem() + view.addItem(xgrid) + view.addItem(ygrid) + view.addItem(zgrid) + + ## rotate x and y grids to face the correct direction + xgrid.rotate(90, 0, 1, 0) + ygrid.rotate(90, 1, 0, 0) + + ## scale each grid differently + xgrid.scale(0.2, 0.1, 0.1) + ygrid.scale(0.2, 0.1, 0.1) + zgrid.scale(0.1, 0.2, 0.1) + + + + + + diff --git a/documentation/source/3dgraphics/glaxisitem.rst b/documentation/source/3dgraphics/glaxisitem.rst new file mode 100644 index 00000000..4f6d02d9 --- /dev/null +++ b/documentation/source/3dgraphics/glaxisitem.rst @@ -0,0 +1,8 @@ +GLAxisItem +========== + +.. autoclass:: pyqtgraph.opengl.GLAxisItem + :members: + + .. automethod:: pyqtgraph.opengl.GLAxisItem.__init__ + diff --git a/documentation/source/3dgraphics/glgraphicsitem.rst b/documentation/source/3dgraphics/glgraphicsitem.rst new file mode 100644 index 00000000..4ff3d175 --- /dev/null +++ b/documentation/source/3dgraphics/glgraphicsitem.rst @@ -0,0 +1,8 @@ +GLGraphicsItem +============== + +.. autoclass:: pyqtgraph.opengl.GLGraphicsItem + :members: + + .. automethod:: pyqtgraph.GLGraphicsItem.__init__ + diff --git a/documentation/source/3dgraphics/glgriditem.rst b/documentation/source/3dgraphics/glgriditem.rst new file mode 100644 index 00000000..11c185c5 --- /dev/null +++ b/documentation/source/3dgraphics/glgriditem.rst @@ -0,0 +1,8 @@ +GLGridItem +========== + +.. autoclass:: pyqtgraph.opengl.GLGridItem + :members: + + .. automethod:: pyqtgraph.opengl.GLGridItem.__init__ + diff --git a/documentation/source/3dgraphics/glmeshitem.rst b/documentation/source/3dgraphics/glmeshitem.rst new file mode 100644 index 00000000..4f23e12e --- /dev/null +++ b/documentation/source/3dgraphics/glmeshitem.rst @@ -0,0 +1,8 @@ +GLMeshItem +========== + +.. autoclass:: pyqtgraph.opengl.GLMeshItem + :members: + + .. automethod:: pyqtgraph.opengl.GLMeshItem.__init__ + diff --git a/documentation/source/3dgraphics/glviewwidget.rst b/documentation/source/3dgraphics/glviewwidget.rst new file mode 100644 index 00000000..7ac39949 --- /dev/null +++ b/documentation/source/3dgraphics/glviewwidget.rst @@ -0,0 +1,8 @@ +GLViewWidget +============ + +.. autoclass:: pyqtgraph.opengl.GLViewWidget + :members: + + .. automethod:: pyqtgraph.opengl.GLViewWidget.__init__ + diff --git a/documentation/source/3dgraphics/glvolumeitem.rst b/documentation/source/3dgraphics/glvolumeitem.rst new file mode 100644 index 00000000..951d78d2 --- /dev/null +++ b/documentation/source/3dgraphics/glvolumeitem.rst @@ -0,0 +1,8 @@ +GLVolumeItem +============ + +.. autoclass:: pyqtgraph.opengl.GLVolumeItem + :members: + + .. automethod:: pyqtgraph.opengl.GLVolumeItem.__init__ + diff --git a/documentation/source/3dgraphics/index.rst b/documentation/source/3dgraphics/index.rst new file mode 100644 index 00000000..b92070a4 --- /dev/null +++ b/documentation/source/3dgraphics/index.rst @@ -0,0 +1,24 @@ +Pyqtgraph's 3D Graphics System +============================== + +The 3D graphics system in pyqtgraph is composed of a :class:`view widget ` and +several graphics items (all subclasses of :class:`GLGraphicsItem `) which +can be added to a view widget. + +**Note:** use of this system requires python-opengl bindings. Linux users should install the python-opengl +packages from their distribution. Windows/OSX users can download from ``_. + +Contents: + +.. toctree:: + :maxdepth: 2 + + glviewwidget + + glgriditem + glmeshitem + glvolumeitem + glaxisitem + glgraphicsitem + meshdata + diff --git a/documentation/source/3dgraphics/meshdata.rst b/documentation/source/3dgraphics/meshdata.rst new file mode 100644 index 00000000..3e08b92e --- /dev/null +++ b/documentation/source/3dgraphics/meshdata.rst @@ -0,0 +1,9 @@ +MeshData +======== + +.. autoclass:: pyqtgraph.opengl.MeshData.MeshData + :members: + + .. automethod:: pyqtgraph.opengl.MeshData.MeshData.__init__ + .. automethod:: pyqtgraph.opengl.MeshData.MeshData.__iter__ + diff --git a/documentation/source/apireference.rst b/documentation/source/apireference.rst index ec303140..85bd1a31 100644 --- a/documentation/source/apireference.rst +++ b/documentation/source/apireference.rst @@ -9,4 +9,5 @@ Contents: functions graphicsItems/index widgets/index - graphicsscene/index \ No newline at end of file + 3dgraphics/index + graphicsscene/index diff --git a/documentation/source/index.rst b/documentation/source/index.rst index 32d15524..5f884b60 100644 --- a/documentation/source/index.rst +++ b/documentation/source/index.rst @@ -16,6 +16,7 @@ Contents: how_to_use plotting images + 3dgraphics style region_of_interest parametertree diff --git a/graphicsItems/PlotCurveItem.py b/graphicsItems/PlotCurveItem.py index 4ce9af46..b9e4042f 100644 --- a/graphicsItems/PlotCurveItem.py +++ b/graphicsItems/PlotCurveItem.py @@ -34,7 +34,7 @@ class PlotCurveItem(GraphicsObject): sigPlotChanged = QtCore.Signal(object) sigClicked = QtCore.Signal(object) - def __init__(self, y=None, x=None, fillLevel=None, copy=False, pen=None, shadowPen=None, brush=None, parent=None, clickable=False): + def __init__(self, x=None, y=None, fillLevel=None, copy=False, pen=None, shadowPen=None, brush=None, parent=None, clickable=False): """ ============== ======================================================= **Arguments:** diff --git a/opengl/MeshData.py b/opengl/MeshData.py index 7ac24aeb..8cd97c3e 100644 --- a/opengl/MeshData.py +++ b/opengl/MeshData.py @@ -3,12 +3,13 @@ import pyqtgraph.functions as fn class MeshData(object): """ - Class for storing 3D mesh data. May contain: - - list of vertex locations - - list of edges - - list of triangles - - colors per vertex, edge, or tri - - normals per vertex or tri + Class for storing and operating on 3D mesh data. May contain: + + - list of vertex locations + - list of edges + - list of triangles + - colors per vertex, edge, or tri + - normals per vertex or tri """ def __init__(self): @@ -26,11 +27,15 @@ class MeshData(object): def setFaces(self, faces, vertexes=None): """ Set the faces in this data set. - Data may be provided either as an Nx3x3 list of floats (9 float coordinate values per face) - *faces* = [ [(x, y, z), (x, y, z), (x, y, z)], ... ] - or as an Nx3 list of ints (vertex integers) AND an Mx3 list of floats (3 float coordinate values per vertex) - *faces* = [ (p1, p2, p3), ... ] - *vertexes* = [ (x, y, z), ... ] + Data may be provided either as an Nx3x3 list of floats (9 float coordinate values per face):: + + faces = [ [(x, y, z), (x, y, z), (x, y, z)], ... ] + + or as an Nx3 list of ints (vertex integers) AND an Mx3 list of floats (3 float coordinate values per vertex):: + + faces = [ (p1, p2, p3), ... ] + vertexes = [ (x, y, z), ... ] + """ if vertexes is None: @@ -147,18 +152,18 @@ class MeshData(object): def edgeColors(self): return self._edgeColors - def reverseNormals(self): - """ - Reverses the direction of all normal vectors. - """ - pass + #def reverseNormals(self): + #""" + #Reverses the direction of all normal vectors. + #""" + #pass - def generateEdgesFromFaces(self): - """ - Generate a set of edges by listing all the edges of faces and removing any duplicates. - Useful for displaying wireframe meshes. - """ - pass + #def generateEdgesFromFaces(self): + #""" + #Generate a set of edges by listing all the edges of faces and removing any duplicates. + #Useful for displaying wireframe meshes. + #""" + #pass def save(self): """Serialize this mesh to a string appropriate for disk storage""" diff --git a/opengl/items/GLAxisItem.py b/opengl/items/GLAxisItem.py index 79d2149d..1586d70a 100644 --- a/opengl/items/GLAxisItem.py +++ b/opengl/items/GLAxisItem.py @@ -5,6 +5,13 @@ from pyqtgraph import QtGui __all__ = ['GLAxisItem'] class GLAxisItem(GLGraphicsItem): + """ + **Bases:** :class:`GLGraphicsItem ` + + Displays three lines indicating origin and orientation of local coordinate system. + + """ + def __init__(self, size=None): GLGraphicsItem.__init__(self) if size is None: diff --git a/opengl/items/GLBoxItem.py b/opengl/items/GLBoxItem.py index 648ac5e4..af888e91 100644 --- a/opengl/items/GLBoxItem.py +++ b/opengl/items/GLBoxItem.py @@ -6,6 +6,11 @@ import pyqtgraph as pg __all__ = ['GLBoxItem'] class GLBoxItem(GLGraphicsItem): + """ + **Bases:** :class:`GLGraphicsItem ` + + Displays a wire-frame box. + """ def __init__(self, size=None, color=None): GLGraphicsItem.__init__(self) if size is None: diff --git a/opengl/items/GLGridItem.py b/opengl/items/GLGridItem.py index e34929b3..35a6f766 100644 --- a/opengl/items/GLGridItem.py +++ b/opengl/items/GLGridItem.py @@ -5,6 +5,12 @@ from pyqtgraph import QtGui __all__ = ['GLGridItem'] class GLGridItem(GLGraphicsItem): + """ + **Bases:** :class:`GLGraphicsItem ` + + Displays a wire-grame grid. + """ + def __init__(self, size=None, color=None): GLGraphicsItem.__init__(self) if size is None: diff --git a/opengl/items/GLMeshItem.py b/opengl/items/GLMeshItem.py index 149baafb..790c6760 100644 --- a/opengl/items/GLMeshItem.py +++ b/opengl/items/GLMeshItem.py @@ -12,13 +12,13 @@ __all__ = ['GLMeshItem'] class GLMeshItem(GLGraphicsItem): """ - Displays a 3D triangle mesh. + **Bases:** :class:`GLGraphicsItem ` + Displays a 3D triangle mesh. """ def __init__(self, faces, vertexes=None): - """ - See MeshData for initialization arguments. + See :class:`MeshData ` for initialization arguments. """ if isinstance(faces, MeshData): self.data = faces diff --git a/opengl/items/GLVolumeItem.py b/opengl/items/GLVolumeItem.py index a261a573..01d8ae48 100644 --- a/opengl/items/GLVolumeItem.py +++ b/opengl/items/GLVolumeItem.py @@ -6,7 +6,23 @@ import numpy as np __all__ = ['GLVolumeItem'] class GLVolumeItem(GLGraphicsItem): + """ + **Bases:** :class:`GLGraphicsItem ` + + Displays volumetric data. + """ + + def __init__(self, data, sliceDensity=1, smooth=True): + """ + ============== ======================================================================================= + **Arguments:** + data Volume data to be rendered. *Must* be 4D numpy array (x, y, z, RGBA) with dtype=ubyte. + sliceDensity Density of slices to render through the volume. A value of 1 means one slice per voxel. + smooth (bool) If True, the volume slices are rendered with linear interpolation + ============== ======================================================================================= + """ + self.sliceDensity = sliceDensity self.smooth = smooth self.data = data