From 2149f9db2977e9fd2ed667a6f8f4d8d7fb64f0cb Mon Sep 17 00:00:00 2001
From: Luke Campagnola <>
Date: Mon, 23 Apr 2012 14:34:54 -0400
Subject: [PATCH] Added documentation on 3D graphics system

---
 documentation/source/3dgraphics.rst           | 48 ++++++++++++++++++
 .../source/3dgraphics/glaxisitem.rst          |  8 +++
 .../source/3dgraphics/glgraphicsitem.rst      |  8 +++
 .../source/3dgraphics/glgriditem.rst          |  8 +++
 .../source/3dgraphics/glmeshitem.rst          |  8 +++
 .../source/3dgraphics/glviewwidget.rst        |  8 +++
 .../source/3dgraphics/glvolumeitem.rst        |  8 +++
 documentation/source/3dgraphics/index.rst     | 24 +++++++++
 documentation/source/3dgraphics/meshdata.rst  |  9 ++++
 documentation/source/apireference.rst         |  3 +-
 documentation/source/index.rst                |  1 +
 graphicsItems/PlotCurveItem.py                |  2 +-
 opengl/MeshData.py                            | 49 ++++++++++---------
 opengl/items/GLAxisItem.py                    |  7 +++
 opengl/items/GLBoxItem.py                     |  5 ++
 opengl/items/GLGridItem.py                    |  6 +++
 opengl/items/GLMeshItem.py                    |  6 +--
 opengl/items/GLVolumeItem.py                  | 16 ++++++
 18 files changed, 197 insertions(+), 27 deletions(-)
 create mode 100644 documentation/source/3dgraphics.rst
 create mode 100644 documentation/source/3dgraphics/glaxisitem.rst
 create mode 100644 documentation/source/3dgraphics/glgraphicsitem.rst
 create mode 100644 documentation/source/3dgraphics/glgriditem.rst
 create mode 100644 documentation/source/3dgraphics/glmeshitem.rst
 create mode 100644 documentation/source/3dgraphics/glviewwidget.rst
 create mode 100644 documentation/source/3dgraphics/glvolumeitem.rst
 create mode 100644 documentation/source/3dgraphics/index.rst
 create mode 100644 documentation/source/3dgraphics/meshdata.rst

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 </3dgraphics/index>` 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 <pyqtgraph.opengl.GLViewWidget>` and 
+several graphics items (all subclasses of :class:`GLGraphicsItem <pyqtgraph.opengl.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 `<http://pyopengl.sourceforge.net>`_.
+
+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 <pyqtgraph.opengl.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 <pyqtgraph.opengl.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 <pyqtgraph.opengl.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 <pyqtgraph.opengl.GLGraphicsItem>`
     
+    Displays a 3D triangle mesh. 
     """
     def __init__(self, faces, vertexes=None):
-        
         """
-        See MeshData for initialization arguments.
+        See :class:`MeshData <pyqtgraph.opengl.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 <pyqtgraph.opengl.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
-- 
GitLab