{
  "nbformat_minor": 0, 
  "nbformat": 4, 
  "cells": [
    {
      "execution_count": null, 
      "cell_type": "code", 
      "source": [
        "%matplotlib inline"
      ], 
      "outputs": [], 
      "metadata": {
        "collapsed": false
      }
    }, 
    {
      "source": [
        "\nUsing OpenGL in PyAnatomist\n---------------------------\n\nCustomizing OpenGL parameters for objects\n\n"
      ], 
      "cell_type": "markdown", 
      "metadata": {}
    }, 
    {
      "execution_count": null, 
      "cell_type": "code", 
      "source": [
        "from __future__ import absolute_import\nfrom soma import aims\nimport anatomist.direct.api as anatomist\nfrom soma.qt_gui.qt_backend import Qt\nfrom OpenGL import GL\nimport six\n\n\nclass VolRender(anatomist.cpp.ObjectVector, anatomist.cpp.GLComponent):\n\n    def __init__(self, objects):\n        self._objects = objects\n        for o in objects:\n            self.insert(o)\n\n    def renderingIsObserverDependent(self):\n        return True\n\n\nclass WinViewMesh (anatomist.cpp.ASurface_3):\n\n    def __init__(self, mesh, followorientation=True, followposition=False):\n        if mesh is not None:\n            if type(mesh) is six.string_types:\n                # mesh is a filename: read it\n                anatomist.cpp.ASurface_3.__init__(self, mesh)\n                r = aims.Reader()\n                m = aims.rc_ptr_AimsTimeSurface_3(r.read(mesh))\n                self.setSurface(m)\n            else:\n                # mesh should be an Aims mesh: assign it\n                anatomist.cpp.ASurface_3.__init__(self)\n                self.setSurface(mesh)\n        else:\n            # generate a sphere mesh\n            anatomist.cpp.ASurface_3.__init__(self)\n            m = aims.rc_ptr_AimsTimeSurface_3(aims.SurfaceGenerator.sphere(\n                                              aims.Point3df(0, 0, 0), 10, 100))\n            self.setSurface(m)\n        self._followorientation = followorientation\n        self._followposition = followposition\n\n    def renderingIsObserverDependent(self):\n        return True\n\n    def glMainGLL(self, state):\n        self.glSetChanged(anatomist.cpp.GLComponent.glGENERAL)\n        return anatomist.cpp.GLComponent.glMainGLL(self, state)\n\n    def glBeforeBodyGLL(self, state, prim):\n        if self._followorientation and self._followposition:\n            return\n        gll = anatomist.cpp.GLList()\n        gll.generate()\n        prim.append(gll)\n        GL.glNewList(gll.item(), GL.GL_COMPILE)\n        GL.glMatrixMode(GL.GL_MODELVIEW)\n        GL.glPushMatrix()\n        GL.glMatrixMode(GL.GL_PROJECTION)\n        GL.glPushMatrix()\n        if not self._followposition:\n            winDim = 70\n            GL.glPushAttrib(GL.GL_VIEWPORT_BIT)\n            GL.glViewport(0, 0, winDim, winDim)\n            GL.glLoadIdentity()\n            orthoMinX = - 1.5\n            orthoMinY = - 1.5\n            orthoMinZ = - 1.5\n            orthoMaxX = 1.5\n            orthoMaxY = 1.5\n            orthoMaxZ = 1.5\n            GL.glOrtho(orthoMinX, orthoMaxX, orthoMinY, orthoMaxY,\n                       orthoMinZ, orthoMaxZ)\n\n        win = state.window\n        if win \\\n                and isinstance(win, anatomist.cpp.ControlledWindow):\n            view = win.view()\n\n        if not self._followorientation:\n            GL.glTranslate(1, 1, 0)\n            # mat = GL.glGetFloatv( GL.GL_MODELVIEW_MATRIX )\n            # scale = aims.Point3df( mat[0][0], mat[1][0], mat[2][0] ).norm()\n            GL.glMatrixMode(GL.GL_MODELVIEW)\n            GL.glLoadIdentity()\n            # keep the translation part of the view orientation\n            # (mut apply the inverse rotation to it)\n            trans = view.rotationCenter()\n            r = aims.AffineTransformation3d(view.quaternion()).inverse()\n            r = r * aims.AffineTransformation3d([1, 0, 0, trans[0],\n                                                 0, 1, 0, trans[1],  0, 0, 1, -trans[2],  0, 0, 0, 1])\n            GL.glTranslate(-r.translation()[0], -r.translation()[1],\n                           -r.translation()[2])\n            GL.glScalef(1., 1., -1.)\n            GL.glMatrixMode(GL.GL_PROJECTION)\n        else:\n            GL.glMatrixMode(GL.GL_MODELVIEW)\n            # keep the rotation part of the view orientation, removing the\n            # translation part\n            trans = view.rotationCenter()\n            r = aims.AffineTransformation3d(view.quaternion()).inverse()\n            r = aims.AffineTransformation3d([1, 0, 0, trans[0],\n                                             0, 1, 0, trans[1],  0, 0, 1, trans[2],  0, 0, 0, 1])\n            GL.glTranslate(r.translation()[0], r.translation()[1],\n                           r.translation()[2])\n            GL.glMatrixMode(GL.GL_PROJECTION)\n\n        GL.glEndList()\n\n    def glAfterBodyGLL(self, state, prim):\n        if self._followorientation and self._followposition:\n            return\n        gll = anatomist.cpp.GLList()\n        gll.generate()\n        prim.append(gll)\n        GL.glNewList(gll.item(), GL.GL_COMPILE)\n        GL.glMatrixMode(GL.GL_PROJECTION)\n        if not self._followposition:\n            GL.glPopAttrib(GL.GL_VIEWPORT_BIT)\n        GL.glPopMatrix()\n        GL.glMatrixMode(GL.GL_MODELVIEW)\n        GL.glPopMatrix()\n        GL.glEndList()\n\n\n# ---\nif __name__ == '__main__':\n    runloop = False\n    if Qt.QApplication.instance() is None:\n        runloop = True\n    a = anatomist.Anatomist()\n    mesh = aims.SurfaceGenerator.sphere((0, 0, 0), 1., 200)\n    amesh = anatomist.cpp.AObjectConverter.anatomist(mesh)\n    cube1 = aims.SurfaceGenerator.cube((0, 0, 0), 0.5, False)\n    vcube1 = WinViewMesh(cube1)\n    a.registerObject(vcube1)\n    cube2 = aims.SurfaceGenerator.cone((0, -0.5, 0), (0, 0.5, 0), 0.5, 50,\n                                       True, False)\n    vcube2 = WinViewMesh(cube2, followorientation=False,\n                         followposition=True)\n    a.registerObject(vcube2)\n    w = a.createWindow('3D')\n    a.addObjects([amesh, vcube1, vcube2], [w])\n\n    import sys\n    if 'sphinx_gallery' in sys.modules:\n        # display in matplotlib for sphinx_gallery\n        import matplotlib\n        w.camera(view_quaternion=[0.535079479217529,\n                                  0.797160744667053,\n                                  0.268512755632401,\n                                  0.0782672688364983],\n                 zoom=0.45)\n        matplotlib.use('agg', force=True)  # force agg\n        w.imshow(show=True)\n        runloop = False\n\n    if runloop:\n        Qt.QApplication.instance().exec_()\n    if runloop or 'sphinx_gallery' in sys.modules:\n        del w, amesh, vcube1, vcube2, cube1, cube2, mesh"
      ], 
      "outputs": [], 
      "metadata": {
        "collapsed": false
      }
    }
  ], 
  "metadata": {
    "kernelspec": {
      "display_name": "Python 2", 
      "name": "python2", 
      "language": "python"
    }, 
    "language_info": {
      "mimetype": "text/x-python", 
      "nbconvert_exporter": "python", 
      "name": "python", 
      "file_extension": ".py", 
      "version": "2.7.17", 
      "pygments_lexer": "ipython2", 
      "codemirror_mode": {
        "version": 2, 
        "name": "ipython"
      }
    }
  }
}