soc-2008-mxcurioni: towards Freestyle's first render: controller, config, appglwidget...
authorMaxime Curioni <maxime.curioni@gmail.com>
Sun, 18 May 2008 13:01:52 +0000 (13:01 +0000)
committerMaxime Curioni <maxime.curioni@gmail.com>
Sun, 18 May 2008 13:01:52 +0000 (13:01 +0000)
35 files changed:
source/blender/freestyle/SConscript
source/blender/freestyle/intern/CHANGELOG.TXT [deleted file]
source/blender/freestyle/intern/app_blender/AppCanvas.cpp [new file with mode: 0755]
source/blender/freestyle/intern/app_blender/AppCanvas.h [new file with mode: 0755]
source/blender/freestyle/intern/app_blender/AppGLWidget.cpp [new file with mode: 0755]
source/blender/freestyle/intern/app_blender/AppGLWidget.h [new file with mode: 0755]
source/blender/freestyle/intern/app_blender/Controller.cpp [new file with mode: 0755]
source/blender/freestyle/intern/app_blender/Controller.h [new file with mode: 0755]
source/blender/freestyle/intern/rendering/GLDebugRenderer.cpp
source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
source/blender/freestyle/misc/AUTHORS.TXT [moved from source/blender/freestyle/intern/AUTHORS.TXT with 100% similarity]
source/blender/freestyle/misc/BUGS.TXT [moved from source/blender/freestyle/intern/BUGS.TXT with 100% similarity]
source/blender/freestyle/misc/COPYRIGHT.TXT [moved from source/blender/freestyle/intern/COPYRIGHT.TXT with 100% similarity]
source/blender/freestyle/misc/Config.pri [moved from source/blender/freestyle/intern/Config.pri with 100% similarity]
source/blender/freestyle/misc/Freestyle-vc7-debug.sln [moved from source/blender/freestyle/intern/Freestyle-vc7-debug.sln with 100% similarity]
source/blender/freestyle/misc/Freestyle-vc7-release.sln [moved from source/blender/freestyle/intern/Freestyle-vc7-release.sln with 100% similarity]
source/blender/freestyle/misc/Freestyle-vc8-debug.sln [moved from source/blender/freestyle/intern/Freestyle-vc8-debug.sln with 100% similarity]
source/blender/freestyle/misc/Freestyle-vc8-release.sln [moved from source/blender/freestyle/intern/Freestyle-vc8-release.sln with 100% similarity]
source/blender/freestyle/misc/INSTALL.TXT [moved from source/blender/freestyle/intern/INSTALL.TXT with 100% similarity]
source/blender/freestyle/misc/LICENSE.TXT [moved from source/blender/freestyle/intern/LICENSE.TXT with 100% similarity]
source/blender/freestyle/misc/Makefile.pro [moved from source/blender/freestyle/intern/Makefile.pro with 100% similarity]
source/blender/freestyle/misc/README.TXT [moved from source/blender/freestyle/intern/README.TXT with 100% similarity]
source/blender/freestyle/misc/THANKS.TXT [moved from source/blender/freestyle/intern/THANKS.TXT with 100% similarity]
source/blender/freestyle/misc/TODO.TXT [moved from source/blender/freestyle/intern/TODO.TXT with 100% similarity]
source/blender/freestyle/misc/build_bundle.macosx.py [moved from source/blender/freestyle/intern/build_bundle.macosx.py with 100% similarity]
source/blender/freestyle/misc/libconfig.pri [moved from source/blender/freestyle/intern/libconfig.pri with 100% similarity]
source/blender/freestyle/misc/makedsp.vcnet.debug.bat [moved from source/blender/freestyle/intern/makedsp.vcnet.debug.bat with 100% similarity]
source/blender/freestyle/misc/makedsp.vcnet.release.bat [moved from source/blender/freestyle/intern/makedsp.vcnet.release.bat with 100% similarity]
source/blender/imbuf/SConscript
source/blender/makesdna/DNA_scene_types.h
source/blender/python/api2_2x/sceneRender.c
source/blender/render/SConscript
source/blender/render/intern/source/pipeline.c
source/blender/src/buttons_scene.c
source/blender/src/renderwin.c

index 6e13af06ee2ce7ceec2c6f427c76ff71d3a813f9..1f5359c5d3927c747834b10ea321ad5defb943bf 100644 (file)
@@ -46,23 +46,25 @@ stroke_sources = env.Glob(prefix + '/*.cpp')
 
 #      rendering
 prefix = 'intern/rendering'
-stroke_sources = env.Glob(prefix + '/GL*.cpp')
+rendering_sources = env.Glob(prefix + '/GL*.cpp')
 
 if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
-       stroke_sources = env.Glob(prefix + '/extgl.cpp')
+       rendering_sources = env.Glob(prefix + '/extgl.cpp')
 
-#      app
+#      app / app_blender
+prefix = 'intern/app_blender'
+app_sources = env.Glob(prefix + '/*.cpp')
 
-sources =      system_sources + image_sources + geometry_sources + scene_graph_sources \
-                       winged_edge_sources + view_map_sources + stroke_sources
-#print sources
+sources =      system_sources + image_sources + geometry_sources + scene_graph_sources \
+                 +     winged_edge_sources + view_map_sources + stroke_sources + rendering_sources \
+                 + app_sources
 
 env.BlenderLib (libname="bf_freestyle",
                                sources=sources,
                 includes=Split(incs),
                 defines=defs,
-                libtype=['blender'],
-                priority = [15] )
+                               libtype=['blender'],
+                priority = [20] )
 
 ########################################################
 # SWIG
diff --git a/source/blender/freestyle/intern/CHANGELOG.TXT b/source/blender/freestyle/intern/CHANGELOG.TXT
deleted file mode 100755 (executable)
index cb9f088..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-2008-03-06 - freestyle-2.2.0
-       * Fixed a bug related to the ViewShape IDs that caused the ray casting to crash.
-       * Fixed a bug in the style module insertion.
-                
-2008-03-02 - freestyle-2.1.1
-       * Added the management of texture coordinates in the scene graph and the rendering.
-       * The reps in the scene graph are now assigned ids based on the lib3ds nodes ids. These ids are transmitted to the WingedEdge Shapes.
-2007-10-05 - freestyle-2.0.1
-
-       * Enforced node construction from lib3ds (thanks to Thomas Netter)
-        * Reverted to not using bundles by default on MacOSX. Activating bundles can be made by uncommenting the lib_bundle line of the CONFIG variable in Config.pri
-        * Added a NodeCamera to the scene graph.
-        * Made sure the display lists were compiled AND executed (GL_COMPILE -> GL_COMPILE_AND_EXECUTE) for IndexedFaceSet.
-        * Added a visitor to deallocate memory on the graphics card (display lists right now).
-        * Modified the grid to use a visitor pattern for ray casting and grid traversal.
-        
-
-
-2007-05-06 - freestyle-2.0.0
-
-       * Switched to Qt 4.2.3, swig 1.3.31, visual c++ 2005, gcc 4.0.1, qglviewer 2.2.5-1
-       * Added texture coordinates to scene graph
-       * Made the grid more robust
-        * Now compiles on MacOSX
-        * Fixed the brush texture problem: the full path to the texture was used instead of the base name and that was breaking the search path algorithm
-
-
-2006-06-18 - freestyle-1.0.2
-
-       * Fixed a bug related to the loading of OpenGL extensions.
-
-
-2005-07-25 - freestyle-1.0.1
-
-       * Upgrade to QGLViewer 2.0.4
-       * Added the FREESTYLE_DIR environment variable.
-         It must be set to the freestyle directory for
-         all releases except the pre-compiled windows version.
-       * Fixed the unix path separator.
-       * Added the "Help>Control bindings" menu action.
-       * Fixed the style modules according to Python 2.4 standards.
-
-
-2005-04-05 - freestyle-1.0.0  
-
-       * Initial release
-
diff --git a/source/blender/freestyle/intern/app_blender/AppCanvas.cpp b/source/blender/freestyle/intern/app_blender/AppCanvas.cpp
new file mode 100755 (executable)
index 0000000..c9ea2d1
--- /dev/null
@@ -0,0 +1,404 @@
+
+//
+//  Copyright (C) : Please refer to the COPYRIGHT file distributed 
+//   with this source distribution. 
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AppGLWidget.h"
+#include "../image/Image.h"
+#include "../system/TimeStamp.h"
+#include "Controller.h"
+#include "../stroke/StrokeRenderer.h"
+#include "AppCanvas.h"
+#include "../rendering/GLRenderer.h"
+#include "../rendering/GLStrokeRenderer.h"
+#include "../rendering/GLUtils.h"
+#include "AppConfig.h"
+#include "../system/StringUtils.h"
+
+#ifdef WIN32
+# include <windows.h>
+# include "../rendering/extgl.h"
+#endif
+#ifdef __MACH__
+# include <OpenGL/gl.h>
+#else
+# include <GL/gl.h>
+#endif
+
+AppCanvas::AppCanvas()
+:Canvas()
+{
+  _pViewer = 0;
+  _blendEquation = true;
+       _MapsPath = StringUtils::toAscii( Config::Path::getInstance()->getMapsDir() ).c_str();
+}
+
+AppCanvas::AppCanvas(AppGLWidget* iViewer)
+:Canvas()
+{
+  _pViewer = iViewer;
+  _blendEquation = true;
+}
+
+AppCanvas::AppCanvas(const AppCanvas& iBrother)
+:Canvas(iBrother)
+{
+  _pViewer = iBrother._pViewer;
+  _blendEquation = iBrother._blendEquation;
+}
+
+AppCanvas::~AppCanvas()
+{
+  _pViewer = 0;
+}
+
+void AppCanvas::SetViewer(AppGLWidget *iViewer)
+{
+  _pViewer = iViewer;
+}  
+
+int AppCanvas::width() const 
+{
+  return _pViewer->width();
+}
+
+int AppCanvas::height() const
+{
+  return _pViewer->height();
+}
+
+BBox<Vec3r> AppCanvas::scene3DBBox() const 
+{
+  return _pViewer->scene3DBBox();
+}
+
+void AppCanvas::preDraw()
+{
+  Canvas::preDraw();
+
+  _pViewer->prepareCanvas();
+  glClearColor(0,0,0,0);
+       glClear(GL_COLOR_BUFFER_BIT);
+       glDisable(GL_LIGHTING);
+       glPolygonMode(GL_FRONT, GL_FILL);
+       glShadeModel(GL_SMOOTH);
+       glDisable(GL_DEPTH_TEST);
+       glEnable(GL_TEXTURE_2D);
+  glEnable(GL_BLEND);
+}
+
+void AppCanvas::init() 
+{
+#ifdef WIN32
+  static bool firsttime = true;
+  if (firsttime)
+    {
+      if (extgl_Initialize() != 0)
+             cerr << "Error: problem occurred while initializing GL extensions" << endl;                       
+      else
+             cout << "GL extensions initialized" << endl;
+
+      if(!glutils_extgl_GetProcAddress("glBlendEquation")){
+        _blendEquation = false;
+        cout << "glBlendEquation unavailable on this hardware -> switching to strokes basic rendering mode" << endl;
+      }
+      firsttime=false;
+    }
+#endif
+
+  _Renderer = new GLStrokeRenderer;
+  if(!StrokeRenderer::loadTextures())
+    {
+      cerr << "unable to load stroke textures" << endl;
+      return;
+    }
+}
+
+void AppCanvas::postDraw()
+{
+  //inverse frame buffer
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+  _pViewer->releaseCanvas();
+
+  Canvas::postDraw();
+}
+
+void AppCanvas::Erase()
+{
+  Canvas::Erase();
+  //_pViewer->clear();
+}
+
+#include "../image/GaussianFilter.h"
+void AppCanvas::readColorPixels(int x,int y,int w, int h, RGBImage& oImage) const
+{
+  //static unsigned number = 0;
+  float *rgb = new float[3*w*h];
+  _pViewer->readPixels(x,y,w,h,AppGLWidget::RGB,rgb);
+  oImage.setArray(rgb, width(), height(), w,h, x, y, false);
+  // FIXME
+  //  QImage qtmp(w, h, 32);
+  //  for(unsigned py=0;py<h;++py){
+  //    for(unsigned px=0;px<w;++px){
+  //      int r = (int)255*(oImage.getR(x+px,y+py));
+  //      int g = (int)255*(oImage.getG(x+px,y+py));
+  //      int b = (int)255*(oImage.getB(x+px,y+py));
+  //      qtmp.setPixel(px,py,qRgb(r,g,b));
+  //    }
+  //  }
+  //  qtmp.save("densityQuery"+QString::number(number)+".png", "PNG");
+  //  if(number == 1090){
+  //    RGBImage img;
+  //    float *rgbtmp = new float[3*width()*height()];
+  //    _pViewer->readPixels(0,0,width(),height(),AppGLWidget::RGB,rgbtmp);
+  //    img.setArray(rgbtmp, width(), height(), width(), height(), 0, 0, false);
+  //    QImage qtmp(width(), height(), 32);
+  //    for(unsigned py=0;py<height();++py){
+  //      for(unsigned px=0;px<width();++px){
+  //        int r = (int)255*(img.getR(px,py));
+  //        int g = (int)255*(img.getG(px,py));
+  //        int b = (int)255*(img.getB(px,py));
+  //        qtmp.setPixel(px,height()-1-py,qRgb(r,g,b));
+  //      }
+  //    }
+  //    qtmp.save("densityQuery"+QString::number(number)+".png", "PNG");
+  //    
+  //    GaussianFilter filter;
+  //    filter.SetSigma(4.0);
+  //    int bound = filter.getBound();
+  //    QImage qtmp2(width(), height(), 32);
+  //    for(int py2=0;py2<height();++py2){
+  //      for(int px2=0;px2<width();++px2){  
+  //        if( (px2-bound < 0) || (px2+bound>width())
+  //         || (py2-bound < 0) || (py2+bound>height()))
+  //          continue;
+  //        int g = 255*filter.getSmoothedPixel<RGBImage>(&img, px2,py2);
+  //        qtmp2.setPixel(px2,height()-1-py2,qRgb(g,g,g));
+  //      }
+  //    }
+  //    qtmp2.save("blurredCausalDensity"+QString::number(number)+".png", "PNG");
+  //  }
+  //  cout << number << endl;
+  //  ++number;
+}
+
+void AppCanvas::readDepthPixels(int x,int y,int w, int h, GrayImage& oImage) const
+{
+  float *rgb = new float[w*h];
+  _pViewer->readPixels(x,y,w,h,AppGLWidget::DEPTH,rgb);
+  oImage.setArray(rgb, width(), height(), w,h, x, y, false);
+}
+
+void AppCanvas::update()
+{
+//  static int counter = 0;
+//  char fileName[100] = "framebuffer";
+//  char number[10];
+//
+  _pViewer->updateGL();
+  _pViewer->swapBuffers();
+  //QImage fb = _pViewer->grabFrameBuffer();
+  //  sprintf(number, "%3d", counter);
+  //  strcat(fileName, number);
+  //  strcat(fileName, ".bmp");
+  //  fb.save(fileName, "BMP");
+  //counter++;
+}
+
+void AppCanvas::Render(const StrokeRenderer *iRenderer)
+{
+  if(!_blendEquation){
+    RenderBasic(iRenderer);
+    return;
+  }
+
+  glClearColor(1,1,1,1);
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glDisable(GL_LIGHTING);
+  glPolygonMode(GL_FRONT, GL_FILL);
+  glShadeModel(GL_SMOOTH);
+  
+  if(_pViewer->draw3DsceneEnabled())
+  {
+    glClearColor(1,1,1,0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    
+    glEnable(GL_LIGHTING);
+    glEnable(GL_DEPTH_TEST);
+    _pViewer->Set3DContext();
+    _pViewer->DrawScene(_pViewer->glRenderer());
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_LIGHTING);
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+  }
+  
+  
+  glDisable(GL_DEPTH_TEST);
+  glBlendEquation(GL_ADD);
+  
+  glBlendFunc(GL_DST_COLOR, GL_ZERO);
+  
+  if(_drawPaper)
+  {
+    glEnable(GL_BLEND);
+    glEnable(GL_TEXTURE_2D);
+    float zfar = _pViewer->zfar();
+    zfar = zfar+0.1*zfar;
+    //draw background paper // FIXME
+    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glBindTexture(GL_TEXTURE_2D, StrokeRenderer::_textureManager->getPaperTextureIndex(_paperTextureIndex)); 
+    glColor4f(1,1,1,0.0);
+    glBegin(GL_TRIANGLE_STRIP);
+    { 
+      glTexCoord2f(0,0); glVertex3f(0, 0, -1);
+      glTexCoord2f(4,0); glVertex3f(2048, 0, -1);
+      glTexCoord2f(0,4); glVertex3f(0, 2048, -1);
+      glTexCoord2f(4,4); glVertex3f(2048, 2048, -1);
+    } 
+    glEnd();
+  }
+  
+  glPushAttrib(GL_COLOR_BUFFER_BIT);
+  glBlendEquation(GL_FUNC_SUBTRACT);
+  glBlendFunc(GL_ONE, GL_ONE);
+  
+  glDisable(GL_TEXTURE_2D);
+  glEnable(GL_BLEND);
+  glColor4f(1,1,1,1);
+  glBegin(GL_TRIANGLE_STRIP);
+  {  
+    glVertex2f(0, 0);
+    glVertex2f(2048, 0);
+    glVertex2f(0, 2048);
+    glVertex2f(2048, 2048);
+  }  
+  glEnd();
+  glPopAttrib();
+  
+  glDisable(GL_DEPTH_TEST);
+  glBlendEquation(GL_ADD);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+  
+  glEnable(GL_TEXTURE_2D);
+  Canvas::Render(iRenderer);
+  //  
+  glPushAttrib(GL_COLOR_BUFFER_BIT);
+  glBlendEquation(GL_FUNC_SUBTRACT);
+  glBlendFunc(GL_ONE, GL_ONE);
+  
+  glDisable(GL_TEXTURE_2D);
+  glEnable(GL_BLEND);
+  glColor3f(1,1,1);
+  glBegin(GL_TRIANGLE_STRIP);
+  { 
+    glVertex2f(0, 0);
+    glVertex2f(2048, 0);
+    glVertex2f(0, 2048);
+    glVertex2f(2048, 2048);
+  } 
+  glEnd();
+  glPopAttrib();
+  
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+}
+
+void AppCanvas::RenderBasic(const StrokeRenderer *iRenderer)
+{
+  glClearColor(1,1,1,1);
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glDisable(GL_LIGHTING);
+  glPolygonMode(GL_FRONT, GL_FILL);
+  glShadeModel(GL_SMOOTH);
+  
+  if(_pViewer->draw3DsceneEnabled())
+  {
+    glClearColor(1,1,1,0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    
+    glEnable(GL_LIGHTING);
+    glEnable(GL_DEPTH_TEST);
+    _pViewer->Set3DContext();
+    _pViewer->DrawScene(_pViewer->glRenderer());
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_LIGHTING);
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+  }
+
+  glBlendFunc(GL_DST_COLOR, GL_ZERO);
+  if(_drawPaper)
+  {
+    glEnable(GL_BLEND);
+    glEnable(GL_TEXTURE_2D);
+    float zfar = _pViewer->zfar();
+    zfar = zfar+0.1*zfar;
+    //draw background paper // FIXME
+    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glBindTexture(GL_TEXTURE_2D, StrokeRenderer::_textureManager->getPaperTextureIndex(_paperTextureIndex)); 
+    glColor4f(1,1,1,0.0);
+    glBegin(GL_TRIANGLE_STRIP);
+    { 
+      glTexCoord2f(0,0); glVertex3f(0, 0, -1);
+      glTexCoord2f(4,0); glVertex3f(2048, 0, -1);
+      glTexCoord2f(0,4); glVertex3f(0, 2048, -1);
+      glTexCoord2f(4,4); glVertex3f(2048, 2048, -1);
+    } 
+    glEnd();
+  }
+
+  glDisable(GL_DEPTH_TEST);
+  glPushAttrib(GL_COLOR_BUFFER_BIT);
+  glEnable(GL_BLEND);
+  glPopAttrib();
+
+  glDisable(GL_DEPTH_TEST);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+  
+  glEnable(GL_TEXTURE_2D);
+  Canvas::RenderBasic(iRenderer);
+
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+}
+
+
+void AppCanvas::RenderStroke(Stroke *iStroke) {
+  iStroke->Render(_Renderer);
+  if(_pViewer->getRecordFlag()){
+    //Sleep(1000);
+     _pViewer->saveSnapshot(true);
+  }
+}
diff --git a/source/blender/freestyle/intern/app_blender/AppCanvas.h b/source/blender/freestyle/intern/app_blender/AppCanvas.h
new file mode 100755 (executable)
index 0000000..773bfc7
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef ARTCANVAS_H
+#define ARTCANVAS_H
+
+#include "../stroke/Canvas.h"
+
+//class AppGLWidget;
+class AppCanvas : public Canvas
+{
+private:
+  mutable AppGLWidget *_pViewer;
+  bool _blendEquation;
+public:
+  AppCanvas();
+  AppCanvas(AppGLWidget *iViewer);
+  AppCanvas(const AppCanvas& iBrother);
+  virtual ~AppCanvas();
+
+  /*! operations that need to be done before a draw */
+  virtual void preDraw();
+  
+  /*! operations that need to be done after a draw */
+  virtual void postDraw();
+  
+  /*! Erases the layers and clears the canvas */
+  virtual void Erase(); 
+  
+  /* init the canvas */
+  virtual void init();
+  
+  /*! Reads a pixel area from the canvas */
+  virtual void readColorPixels(int x,int y,int w, int h, RGBImage& oImage) const;
+  /*! Reads a depth pixel area from the canvas */
+  virtual void readDepthPixels(int x,int y,int w, int h, GrayImage& oImage) const;
+
+  virtual BBox<Vec3r> scene3DBBox() const ;
+
+  /*! update the canvas (display) */
+  virtual void update() ;
+
+  /*! Renders the created strokes */
+  virtual void Render(const StrokeRenderer *iRenderer);
+  virtual void RenderBasic(const StrokeRenderer *iRenderer);
+  virtual void RenderStroke(Stroke *iStroke) ;
+
+  /*! accessors */
+  virtual int width() const ;
+  virtual int height() const ;
+  inline const AppGLWidget * viewer() const {return _pViewer;}
+
+  /*! modifiers */
+  void SetViewer(AppGLWidget *iViewer) ;
+};
+
+
+#endif
diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget.cpp
new file mode 100755 (executable)
index 0000000..44e25ee
--- /dev/null
@@ -0,0 +1,611 @@
+
+//
+//  Copyright (C) : Please refer to the COPYRIGHT file distributed 
+//   with this source distribution. 
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <iostream>
+#include "../stroke/Canvas.h"
+#include "AppGLWidget.h"
+#include "../scene_graph/NodeLight.h"
+#include "../rendering/GLRenderer.h"
+#include "../rendering/GLSelectRenderer.h"
+#include "../rendering/GLBBoxRenderer.h"
+#include "../rendering/GLMonoColorRenderer.h"
+#include "Controller.h"
+#include "../view_map/Silhouette.h"
+#include "../view_map/ViewMap.h"
+#include "../scene_graph/LineRep.h"
+#include "../scene_graph/NodeShape.h"
+#include "../scene_graph/VertexRep.h"
+#include "AppConfig.h"
+
+#include "../system/StringUtils.h"
+#include "BLI_blenlib.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+// glut.h must be included last to avoid a conflict with stdlib.h on vc .net 2003 and 2005
+#ifdef __MACH__
+# include <GLUT/glut.h>
+#else
+# include <GL/glut.h>
+#endif
+
+GLuint texture = 0;
+
+bool AppGLWidget::_frontBufferFlag = false;
+bool AppGLWidget::_backBufferFlag = true;
+
+AppGLWidget::AppGLWidget(const char *iName)
+{
+  _Fovy        = 30.f;
+  //_SceneDepth = 2.f;
+  _RenderStyle = LINE;
+  //_ModelRootNode->SetBBox(BBox<Vec3f>(Vec3f(-10.f, -10.f, -10.f), Vec3f(10.f, 10.f, 10.f)));
+  _ModelRootNode = new NodeDrawingStyle;
+  _SilhouetteRootNode = new NodeDrawingStyle;
+  _DebugRootNode = new NodeDrawingStyle;
+  
+  _RootNode.AddChild(_ModelRootNode);
+  _SilhouetteRootNode->SetStyle(DrawingStyle::LINES);
+  _SilhouetteRootNode->SetLightingEnabled(false);
+  _SilhouetteRootNode->SetLineWidth(2.f);
+  _SilhouetteRootNode->SetPointSize(3.f);
+
+  _RootNode.AddChild(_SilhouetteRootNode);
+
+  _DebugRootNode->SetStyle(DrawingStyle::LINES);
+  _DebugRootNode->SetLightingEnabled(false);
+  _DebugRootNode->SetLineWidth(1.f);
+  
+  _RootNode.AddChild(_DebugRootNode);
+
+  _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], 
+                            _ModelRootNode->bbox().getMin()[1]),
+                      _ModelRootNode->bbox().getMin()[2]);
+  _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], 
+                            _ModelRootNode->bbox().getMax()[1]),
+                      _ModelRootNode->bbox().getMax()[2]);
+
+  _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox));
+  _minAbs = __min(rabs(_minBBox), rabs(_maxBBox));
+
+  _camera->setZNearCoefficient(0.1);
+
+  // 2D Scene
+  //  _pFENode = new NodeDrawingStyle;
+  //  _pFENode->SetStyle(DrawingStyle::LINES);
+  //  _pFENode->SetLightingEnabled(false);
+  //  _pFENode->SetLineWidth(1.f);
+  //
+  //  _p2DNode.AddChild(_pFENode);
+  //  
+  //  _pVisibleSilhouetteNode = new NodeDrawingStyle;
+  //  _pVisibleSilhouetteNode->SetStyle(DrawingStyle::LINES);
+  //  _pVisibleSilhouetteNode->SetLightingEnabled(false);
+  //  _pVisibleSilhouetteNode->SetLineWidth(3.f);
+  //
+  //  _p2DNode.AddChild(_pVisibleSilhouetteNode);
+  //  
+  _p2DSelectionNode = new NodeDrawingStyle;
+  _p2DSelectionNode->SetLightingEnabled(false);
+  _p2DSelectionNode->SetStyle(DrawingStyle::LINES);
+  _p2DSelectionNode->SetLineWidth(5.f);
+  
+  _p2DNode.AddChild(_p2DSelectionNode);
+
+  _pGLRenderer = new GLRenderer;
+  _pSelectRenderer = new GLSelectRenderer;
+  _pBBoxRenderer = new GLBBoxRenderer;
+  _pMonoColorRenderer = new GLMonoColorRenderer;
+  _pDebugRenderer = new GLDebugRenderer;
+
+  _pMainWindow = NULL;
+  _cameraStateSaved = false;
+  _drawBBox = false;
+  _silhouette = false;
+  _fedges = false;
+  _debug = false;
+  _selection_mode = false;
+  _Draw2DScene = true;
+  _Draw3DScene = true;
+  _drawEnvMap = false;
+  _currentEnvMap = 1;
+  _maxId = 0;
+  _blendFunc = 0;
+
+  const string sep(Config::DIR_SEP);
+  const string filename = Config::Path::getInstance()->getHomeDir() + sep +
+    Config::OPTIONS_DIR + sep + Config::OPTIONS_QGLVIEWER_FILE;
+  setStateFileName(filename);  
+
+  //get camera frame:
+  //qglviewer::Camera * cam = camera();
+  //qglviewer::ManipulatedFrame *  fr = cam->frame() ;
+  
+  //soc _enableupdateSilhouettes = false;
+
+  _captureMovie = false;
+  //  _frontBufferFlag = false;
+  //  _backBufferFlag = true;
+  _record = false;
+
+_camera = new Camera;
+
+}
+
+AppGLWidget::~AppGLWidget()
+{
+  int ref = _RootNode.destroy();
+  
+  _Light.destroy();
+  ref = _p2DNode.destroy();
+  
+  if(NULL != _pGLRenderer)
+    {
+      delete _pGLRenderer;
+      _pGLRenderer = NULL;
+    }
+
+  if(NULL != _pSelectRenderer)
+    {
+      delete _pSelectRenderer;
+      _pSelectRenderer = NULL;
+    }
+
+  if(NULL != _pBBoxRenderer)
+    {
+      delete _pBBoxRenderer;
+      _pBBoxRenderer = NULL;
+    }
+
+  if(NULL != _pMonoColorRenderer)
+    {
+      delete _pMonoColorRenderer;
+      _pMonoColorRenderer = NULL;
+    }
+
+  if(NULL != _pDebugRenderer)
+    {
+      delete _pDebugRenderer;
+      _pDebugRenderer = NULL;
+    }
+
+  makeCurrent();
+  //saveToFile(filename);
+}
+
+
+
+void AppGLWidget::LoadEnvMap(const char *filename)
+{
+  GLuint textureId;
+  //sgiImage img;
+  //cout << filename << endl;
+       ImBuf *image = IMB_loadiffname(filename, 0);
+
+  //data = img.read(filename); // tres beau bleu gris mauve!!
+  // allocate a texture name
+  glGenTextures( 1, &textureId );
+  if(textureId > (GLuint) _maxId)
+    _maxId = textureId;
+
+  // select our current texture
+  glBindTexture( GL_TEXTURE_2D, textureId );
+  
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+                   GL_NEAREST);
+
+  glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, image->x, image->y, 0,
+    GL_RGBA, GL_UNSIGNED_BYTE, image->rect );
+}
+
+void AppGLWidget::init()
+{
+  //setShortcut(QGLViewer::EXIT_VIEWER, 0);
+//  setShortcut(QGLViewer::DISPLAY_Z_BUFFER, 0);
+  //setShortcut(QGLViewer::STEREO, 0);
+  //setShortcut(QGLViewer::ANIMATION, 0);
+  //setShortcut(QGLViewer::EDIT_CAMERA, 0);
+
+  //restoreStateFromFile();
+
+  //trackball().fitBBox(_ModelRootNode->bbox().getMin(), _ModelRootNode->bbox().getMax(), _Fovy);
+
+   glClearColor(1,1,1,0);
+   glShadeModel(GL_SMOOTH);
+  
+   glCullFace(GL_BACK);
+   glEnable(GL_CULL_FACE);
+   glEnable(GL_DEPTH_TEST);
+
+   // open and read texture data
+   Config::Path * cpath = Config::Path::getInstance();
+   string envmapDir = cpath->getEnvMapDir();
+       LoadEnvMap( StringUtils::toAscii(envmapDir + string("gray00.png")).c_str() );
+   //LoadEnvMap(Config::ENV_MAP_DIR + "gray01.bmp");
+   LoadEnvMap( StringUtils::toAscii(envmapDir + string("gray02.png")).c_str() );
+   LoadEnvMap( StringUtils::toAscii(envmapDir + string("gray03.png")).c_str() );
+   LoadEnvMap( StringUtils::toAscii(envmapDir + string("brown00.png")).c_str() );
+   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) ;
+   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) ;
+
+   // gl settings for Environmental Texturing:
+   glColor3f(1, 1, 1);
+
+   // Use GL auto-computed enviroment texture coordinates
+   //glEnable(GL_TEXTURE_GEN_S);
+   //glEnable(GL_TEXTURE_GEN_T);
+
+   // Bind the texture to use
+   //glBindTexture(GL_TEXTURE_2D,texture);
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+   //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+   
+   // parametres de melange
+   //glBlendFunc(GL_ONE, GL_ONE);
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+   //glBlendEquatio(GL_FUNC_ADD);
+     
+   //glEnable(GL_BLEND);
+   NodeLight *light = new NodeLight;
+   _Light.AddChild(light);
+
+   // Change QGLViewer's default shortcut for snapshots
+   //setShortcut(QGLViewer::SAVE_SCREENSHOT, Qt::CTRL + Qt::Key_W);
+   //   setShortcutKey (QGLViewer::SAVE_SCREENSHOT, Key_W);
+   //   setShortcutStateKey(QGLViewer::SAVE_SCREENSHOT, ControlButton);
+  
+   cout << "Renderer (GL)    : " << glGetString(GL_RENDERER) << endl
+       << "Vendor (GL)      : " << glGetString(GL_VENDOR) << endl << endl;
+}
+
+void AppGLWidget::draw()
+{
+  if (true == _Draw3DScene)
+    {
+      if (true == _selection_mode) {
+       _pSelectRenderer->setSelectRendering(false);
+       _pSelectRenderer->resetColor();
+       DrawScene(_pSelectRenderer);
+      } else
+       DrawScene(_pGLRenderer);
+  
+      if (true == _silhouette)
+       DrawSilhouette();
+  
+      if (true == _drawBBox) {
+       glPushAttrib(GL_ALL_ATTRIB_BITS);
+       _ModelRootNode->accept(*_pBBoxRenderer);
+       glPopAttrib();
+      }
+
+      if (true == _debug) {
+       glPushAttrib(GL_ALL_ATTRIB_BITS);
+       _DebugRootNode->accept(*_pDebugRenderer);
+       glPopAttrib();
+      }
+    }
+
+  if (true == _Draw2DScene) {
+    Draw2DScene(_pGLRenderer);
+    Set3DContext();
+  }
+  if(_record){
+    saveSnapshot(true);
+  }
+}
+
+void AppGLWidget::DrawScene(SceneVisitor *iRenderer)
+{
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+  if(_drawEnvMap)
+  {
+    _ModelRootNode->SetLightingEnabled(false);
+    glEnable(GL_COLOR_MATERIAL);
+
+    glEnable(GL_TEXTURE_2D);
+    // Bind the texture to use
+    glBindTexture(GL_TEXTURE_2D,_currentEnvMap); 
+    switch(_blendFunc)
+    {
+    case 0:
+      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ;
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+      glEnable(GL_BLEND);
+      break;
+    case 1:
+      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) ;
+      glDisable(GL_BLEND);
+      break;
+      //    case 2:
+      //      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ;
+      //      glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
+      //      glEnable(GL_BLEND);
+      //      break;
+      //    case 3:
+      //      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ;
+      //      glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); 
+      //      glEnable(GL_BLEND);
+      //      break;
+      //    case 4:
+      //      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ;
+      //      glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); 
+      //      glEnable(GL_BLEND);
+      //      break;
+    default:
+      break;
+    }
+
+    glEnable(GL_TEXTURE_GEN_S);
+    glEnable(GL_TEXTURE_GEN_T);
+  }
+
+  // FIXME
+  //  //_ModelRootNode->SetLightingEnabled(true);
+  //  if(_ModelRootNode->style() == DrawingStyle::LINES){
+  //    glPushAttrib(GL_ALL_ATTRIB_BITS);
+  //    //glDisable(GL_COLOR_MATERIAL);
+  //    _ModelRootNode->SetStyle(DrawingStyle::FILLED);
+  //    _ModelRootNode->SetLightingEnabled(true);
+  //    _ModelRootNode->accept(*iRenderer);  
+  //    _ModelRootNode->SetStyle(DrawingStyle::LINES);
+  //    _ModelRootNode->SetLightingEnabled(false);
+  //    _ModelRootNode->accept(*iRenderer);  
+  //    glPopAttrib();
+  //  }
+  //  else
+  _ModelRootNode->accept(*iRenderer);
+
+  glDisable(GL_TEXTURE_GEN_S);
+  glDisable(GL_TEXTURE_GEN_T);
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_COLOR_MATERIAL);
+  _ModelRootNode->SetLightingEnabled(true);
+
+  if(_fedges == true)
+    _SilhouetteRootNode->accept(*iRenderer);
+
+  // FIXME: deprecated
+//   if(_debug == true)
+//     _DebugRootNode->accept(*iRenderer);
+  
+  glPopAttrib();
+}
+
+void AppGLWidget::prepareCanvas()
+{
+  makeCurrent();
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+  if(_frontBufferFlag){
+    if(_backBufferFlag)
+      glDrawBuffer(GL_FRONT_AND_BACK);
+    else
+      glDrawBuffer(GL_FRONT);
+  }
+  else if(_backBufferFlag)
+    glDrawBuffer(GL_BACK);
+  
+  // Projection Matrix
+  //==================
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  
+  glOrtho(0,width(), 0, height(), -1.0, 1.0);
+  
+  //Modelview Matrix
+  //================
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+}
+
+void AppGLWidget::releaseCanvas()
+{
+  makeCurrent();
+  glDrawBuffer(GL_BACK);
+  glPopAttrib();
+}
+
+void AppGLWidget::Draw2DScene(SceneVisitor *iRenderer)
+{
+  static bool first = 1;
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+//    // Projection Matrix
+//    //==================
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(0,width(), 0, height(), -1.0, 1.0);
+
+//    //Modelview Matrix
+//    //================
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+
+  //  glBegin(GL_LINE_LOOP);
+  //  glVertex2f(0,0);
+  //  glVertex2f(100,0);
+  //  glVertex2f(100,100);
+  //  glVertex2f(0,100);
+  //  glEnd();
+
+  //glDrawBuffer(GL_FRONT_AND_BACK);
+  // Draw visible silhouette
+  //_pVisibleSilhouetteNode->Render(iRenderer);
+  Canvas * canvas = Canvas::getInstance();
+  if((canvas) && (!canvas->isEmpty()))
+  {
+    if (first)
+    {
+      canvas->init();
+      first = false;
+    }
+    canvas->Render(canvas->renderer());
+  }
+  
+  glLoadIdentity();
+  //  glColor3f(0.f,1.f,0.f);
+  //  glLineWidth(5.f);
+  //glPolygonOffset(0.5f, 0.5f);
+  glPushAttrib(GL_DEPTH_BUFFER_BIT);
+  glDisable(GL_DEPTH_TEST);
+  _p2DSelectionNode->accept(*iRenderer);
+  glPopAttrib();
+  // Draw Feature edges
+  //  if(_fedges == true)
+  //  {
+  //    _pFENode->Render(iRenderer);
+  //  }
+  glPopAttrib();
+}
+
+void AppGLWidget::DrawSilhouette()
+{
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+  
+  glDepthFunc(GL_LESS);
+  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+  DrawScene(_pMonoColorRenderer);
+
+  glCullFace(GL_FRONT);
+  glDepthFunc(GL_LEQUAL);
+  glEnable(GL_POLYGON_OFFSET_FILL);
+  glLineWidth(3.0);
+  //glPolygonOffset(10.f, 10.f);
+  glPolygonOffset(0.5f, 0.5f);
+  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+  _pMonoColorRenderer->setColor(0.f, 0.f, 0.f);
+  DrawScene(_pMonoColorRenderer);
+
+  //Restore old context
+  glPopAttrib();
+
+}
+
+void AppGLWidget::ReInitRenderers()
+{
+  // Debug Renderer
+  if(NULL != _pDebugRenderer)
+    _pDebugRenderer->ReInit(rabs(_ModelRootNode->bbox().getMax()[1] -
+                                _ModelRootNode->bbox().getMin()[1]));
+}
+
+void AppGLWidget::setFrontBufferFlag(bool iBool){
+  _frontBufferFlag = iBool;
+}
+bool AppGLWidget::getFrontBufferFlag() {
+  return _frontBufferFlag;
+}
+void AppGLWidget::setBackBufferFlag(bool iBool){
+  _backBufferFlag = iBool;
+}
+bool AppGLWidget::getBackBufferFlag() {
+  return _backBufferFlag;
+}
+
+//void AppGLWidget::DrawLines()
+//{
+//  //Antialiasing:
+//  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+//  glEnable(GL_BLEND);
+//  glEnable(GL_LINE_SMOOTH);
+//  glPolygonMode(GL_FRONT, GL_LINE);
+//
+//  glColor3f(0.f, 0.f, 0.f);
+//  glLineWidth(2.f);
+//
+//  DrawScene();
+//}
+//
+//void AppGLWidget::DrawSurfacic()
+//{
+//  glPolygonMode(GL_FRONT, GL_FILL);
+//  glShadeModel(GL_SMOOTH);
+//  
+//  glEnable(GL_LIGHTING);
+//  glEnable(GL_LIGHT0);
+//
+//  
+//  GLreal diffuseV[] = {0.5, 0.7, 0.5, 1.0};
+//  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseV);
+//
+//  //glColor3f(0.f, 0.f, 0.f);
+//
+//  DrawScene();
+//
+//  glDisable(GL_LIGHTING);
+//}
+//
+//void AppGLWidget::DrawDepthBuffer()
+//{
+//  GLint w = width();
+//  GLint h = height();
+//
+//  glPolygonMode(GL_FRONT, GL_FILL);
+//  
+//  //Disable the writing in the frame buffer
+//  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+//
+//  //This rendering will only fills the depth buffer
+//  DrawScene();
+//
+//  //Re-enable the frame buffer writing
+//  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+//
+//
+//  GLreal *zPixels = new real[w*h];
+//  GLreal *colorPixels = new real[4*w*h];
+//
+// // glReadBuffer(GL_FRONT); //in reality: glReadBuffer and glDrawBuffer are both set to GL_BACK
+//  glReadPixels(0,0,w, h, GL_DEPTH_COMPONENT, GL_real, (GLreal*)zPixels);
+//
+//  real *tmpZ = zPixels;
+//  real *tmpColor = colorPixels;
+//
+//  for(int i=0; i<h; i++)
+//  {
+//    for(int j=0; j<w; j++)
+//    {
+//      //fprintf(test, " %.5f ", pixels[i*w+j]);
+//      tmpColor[0] = *tmpZ;
+//      tmpColor[1] = *tmpZ;
+//      tmpColor[2] = *tmpZ;
+//      tmpColor[3] = 1.f;
+//
+//      tmpColor += 4;
+//      tmpZ++;
+//    }
+//  }
+//  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+// // glDrawBuffer(GL_FRONT_AND_BACK);
+//  //glRasterPos2i(0, 0);
+//  //glLoadIdentity();
+//  glDrawPixels(w, h, GL_RGBA, GL_real, (GLreal *)colorPixels);
+//    
+//  delete [] zPixels;
+//  delete [] colorPixels;  
+//}
+
diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget.h b/source/blender/freestyle/intern/app_blender/AppGLWidget.h
new file mode 100755 (executable)
index 0000000..0d10049
--- /dev/null
@@ -0,0 +1,593 @@
+//
+//  Filename         : AppConfig.h
+//  Author           : Stephane Grabli
+//  Purpose          : Configuration file
+//  Date of creation : 26/02/2003
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//
+//  Copyright (C) : Please refer to the COPYRIGHT file distributed 
+//   with this source distribution. 
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef  ARTGLWIDGET_H
+# define ARTGLWIDGET_H
+
+# ifndef WIN32
+#  include <algorithm>
+using namespace std;
+#  define __min(x,y) (min(x,y))
+#  define __max(x,y) (max(x,y))
+# endif // WIN32
+
+
+//# include <qstringlist.h>
+# include "../geometry/Geom.h"
+# include "../geometry/BBox.h"
+# include "../scene_graph/NodeDrawingStyle.h"
+# include "../system/TimeUtils.h"
+# include "../system/Precision.h"
+# include "AppConfig.h"
+# include "../rendering/GLDebugRenderer.h"
+//# include <QGLViewer/qglviewer.h>
+
+using namespace Geometry;
+
+typedef enum {SURFACIC, LINE, DEPTHBUFFER} RenderStyle;
+
+class FEdge;
+class QMainWindow;
+class GLRenderer;
+class GLSelectRenderer;
+class GLBBoxRenderer;
+class GLMonoColorRenderer;
+class GLDebugRenderer;
+
+class Vec{
+public:
+       Vec() {};
+       Vec(float _x, float _y, float _z): x(_x), y(_y), z(_z) {};
+       ~Vec() {}
+       
+       float operator[] (unsigned i) {
+               switch(i){
+               case 0: return x; break;
+               case 1: return y; break;
+               case 2: return z; break;
+               }
+               return 0.0;
+       }
+               
+       
+       float x,y,z;
+};
+
+class Quaternion{
+public:
+       Quaternion( float _x, float _y, float _z, float _s): x(_x), y(_y), z(_z), s(_s){};
+       ~Quaternion() {}
+       
+       float operator[] (unsigned i) {
+               switch(i){
+               case 0: return x; break;
+               case 1: return y; break;
+               case 2: return z; break;
+               case 3: return s; break;
+               }
+               return 0.0;
+       }
+       
+       float x,y,z,s;
+};
+
+class Camera {
+       private:
+               float _position[3];
+               float _orientation[3];
+               
+       public:
+               Camera(){};
+               ~Camera() {};
+               
+               void setZNearCoefficient(float f) {}
+               void playPath(int i) {}
+
+               void loadProjectionMatrix() {}
+               void loadModelViewMatrix() {}
+               real distanceToSceneCenter() { return 0;}
+               void showEntireScene() {} 
+               real zFar() {return 0;}
+               real zNear() {return 0;}
+               void setPosition(Vec v) {}
+               void setOrientation(Quaternion q) {}
+               float* position() { return _position; }
+               float* orientation()  { return _orientation; }
+               void getWorldCoordinatesOf(float *src, float *vp_tmp) {}
+
+};
+
+
+//class AppGLWidget : public QGLViewer
+class AppGLWidget
+{
+  //Q_OBJECT
+
+    
+public:
+
+  AppGLWidget(const char *iName = 0);
+  virtual ~AppGLWidget();
+  
+public:
+
+       inline void swapBuffers() {}
+  inline void updateGL() {}
+  inline void makeCurrent() {}
+  inline void setSceneBoundingBox(Vec &min_, Vec &max_) {}
+       inline void saveSnapshot(bool b) {}
+       inline real width() { return _width; }
+       inline real height() { return _height; }
+        void setStateFileName(const string& name) { stateFileName_ = name; };
+       
+       
+Camera * _camera;
+
+  // captures a frame animation that was previously registered
+  void captureMovie();
+
+  /*! Sets the rendering style.
+        iStyle
+          The style used to render. Can be:
+          SURFACIC    : usual rendering
+          LINES       : line rendering
+          DEPTHBUFFER : grey-levels rendering of the depth buffer
+          */
+  inline void SetRenderStyle(RenderStyle iStyle)
+  {
+    _RenderStyle = iStyle;
+  }
+
+  /*! Sets the model to draw in the viewer 
+   *  iModel
+   *    The Root Node of the model 
+   */
+  inline void SetModel(NodeGroup *iModel)
+  {
+    if(0 != _ModelRootNode->numberOfChildren())
+    {
+      _ModelRootNode->DetachChildren();
+      _ModelRootNode->clearBBox();
+    }
+      
+    AddModel(iModel);
+  }
+
+  /*! Adds a model for displaying in the viewer */
+  inline void AddModel(NodeGroup *iModel) 
+  {
+    _ModelRootNode->AddChild(iModel);
+    
+    _ModelRootNode->UpdateBBox();
+
+    _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], 
+                            _ModelRootNode->bbox().getMin()[1]),
+                      _ModelRootNode->bbox().getMin()[2]);
+    _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], 
+                            _ModelRootNode->bbox().getMax()[1]),
+                      _ModelRootNode->bbox().getMax()[2]);
+    
+     _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox));
+
+     _minAbs = __min(rabs(_minBBox), rabs(_maxBBox));
+
+     // DEBUG:
+    ReInitRenderers();
+  }
+
+  inline void AddSilhouette(NodeGroup* iSilhouette)
+  {
+    _SilhouetteRootNode->AddChild(iSilhouette);
+    //ToggleSilhouette(true);
+    updateGL();
+  }
+
+  inline void Add2DSilhouette(NodeGroup *iSilhouette)
+  {
+    //_pFENode->AddChild(iSilhouette);
+    //ToggleSilhouette(true);
+    updateGL();
+  }
+
+  inline void Add2DVisibleSilhouette(NodeGroup *iVSilhouette)
+  {
+    //_pVisibleSilhouetteNode->AddChild(iVSilhouette);
+    updateGL();
+  }
+
+  inline void SetDebug(NodeGroup* iDebug)
+  {
+    if(0 != _DebugRootNode->numberOfChildren())
+    {
+      _DebugRootNode->DetachChildren();
+      _DebugRootNode->clearBBox();
+    }
+      
+    AddDebug(iDebug);
+  }
+
+  inline void AddDebug(NodeGroup* iDebug)
+  {
+    _DebugRootNode->AddChild(iDebug);
+    updateGL();
+  }
+
+  inline void DetachModel(Node *iModel)
+  {
+    _ModelRootNode->DetachChild(iModel);
+    _ModelRootNode->UpdateBBox();
+    
+    _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], 
+                            _ModelRootNode->bbox().getMin()[1]),
+                      _ModelRootNode->bbox().getMin()[2]);
+    _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], 
+                            _ModelRootNode->bbox().getMax()[1]),
+                      _ModelRootNode->bbox().getMax()[2]);
+    
+     _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox));
+     _minAbs = __min(rabs(_minBBox), rabs(_maxBBox));
+  } 
+
+  inline void DetachModel() 
+  {
+    _ModelRootNode->DetachChildren();
+    _ModelRootNode->clearBBox();
+    
+    // 2D Scene
+    //_p2DNode.DetachChildren();
+    //_pFENode->DetachChildren();
+    //_pVisibleSilhouetteNode->DetachChildren();
+    updateGL();
+  }
+
+  inline void DetachSilhouette()
+  {
+    _SilhouetteRootNode->DetachChildren();
+    //_pFENode->DetachChildren();
+    //_pVisibleSilhouetteNode->DetachChildren();
+    _p2DSelectionNode->destroy();
+    //updateGL(); //FIXME
+  }
+
+  inline void DetachVisibleSilhouette()
+  {
+    //_pVisibleSilhouetteNode->DetachChildren();
+    _p2DSelectionNode->destroy();
+    updateGL();
+  }
+
+  inline void DetachDebug()
+  {
+    _DebugRootNode->DetachChildren();
+    updateGL();
+  }
+
+  void SetMainWindow(QMainWindow *iMainWindow) ;
+
+  inline void Set3DContext()
+  {
+    // GL_PROJECTION matrix
+    _camera->loadProjectionMatrix();
+    // GL_MODELVIEW matrix
+    _camera->loadModelViewMatrix();
+  }
+  
+  inline void RetriveModelViewMatrix(float *p)
+  {
+    makeCurrent();
+    glGetFloatv(GL_MODELVIEW_MATRIX, p);
+  }
+  inline void RetriveModelViewMatrix(real *p)
+  {
+    makeCurrent();
+    glGetDoublev(GL_MODELVIEW_MATRIX, p);
+  }
+
+  inline void RetrieveProjectionMatrix(float *p)
+  {
+    makeCurrent();
+    glGetFloatv(GL_PROJECTION_MATRIX, p);
+
+  }
+  inline void RetrieveProjectionMatrix(real *p)
+  {
+    makeCurrent();
+    glGetDoublev(GL_PROJECTION_MATRIX, p);
+
+  }
+
+  inline void RetrieveViewport(int *p)
+  {
+    makeCurrent();
+    glGetIntegerv(GL_VIEWPORT,(GLint *)p);
+  }
+  
+  inline real GetFocalLength() const
+  {
+    real Near =  __max(0.1,(real)(-2.f*_maxAbs+_camera->distanceToSceneCenter()));
+    return Near;
+  }
+
+  inline real GetAspect() const
+  {
+    return ((real) _width/(real) _height);
+  }
+
+  inline real GetFovyRadian() const
+  {
+    return _Fovy/180.0 * M_PI;
+  }
+
+  inline real GetFovyDegrees() const
+  {
+    return _Fovy;
+  }
+
+  inline void FitBBox()
+  {
+       Vec min_(_ModelRootNode->bbox().getMin()[0],
+                       _ModelRootNode->bbox().getMin()[1],
+                       _ModelRootNode->bbox().getMin()[2]);
+       Vec max_(_ModelRootNode->bbox().getMax()[0],
+                       _ModelRootNode->bbox().getMax()[1],
+                       _ModelRootNode->bbox().getMax()[2]);
+    setSceneBoundingBox(min_, max_);
+    _camera->showEntireScene();
+  }
+  
+  inline void ToggleSilhouette(bool enabled) 
+  {
+    _fedges = enabled;
+    updateGL();
+  }
+  
+  // Reinit the renderers which need to be informed
+  // when a model is added to the scene.
+  void ReInitRenderers();
+
+  inline void SetSelectedFEdge(FEdge* iFEdge) { _pDebugRenderer->SetSelectedFEdge(iFEdge); }
+
+  inline GLDebugRenderer* debugRenderer() { return _pDebugRenderer; }
+  inline void toggle3D() { _Draw3DScene == true ? _Draw3DScene = false : _Draw3DScene = true; updateGL();}
+
+  /*! glReadPixels */
+  typedef enum{
+    RGB,
+    DEPTH
+  } PixelFormat;
+  void readPixels(int x,
+                  int y,
+                  int width,
+                  int height,
+                  PixelFormat format,
+                  float *pixels) 
+  {
+    makeCurrent();
+    //glReadBuffer(GL_FRONT); //in reality: glReadBuffer and glDrawBuffer are both set to GL_BACK
+    glReadBuffer(GL_BACK);
+    GLenum glformat;
+    switch(format)
+    {
+    case RGB:
+      glformat = GL_RGB;
+      break;
+    case DEPTH:
+      glformat = GL_DEPTH_COMPONENT;
+      break;
+    default:
+      break;
+    }
+    glReadPixels(x,y,width, height, glformat, GL_FLOAT, (GLfloat*)pixels);
+  }
+
+  void clear() { makeCurrent(); glClear(GL_COLOR_BUFFER_BIT ); }
+
+  void prepareCanvas();
+  void releaseCanvas();
+
+  typedef enum {
+    FRONT,
+    BACK
+  } GLBuffer;
+
+  void setReadPixelsBuffer(int iBuffer) 
+  {
+    makeCurrent();
+    switch(iBuffer)
+    {
+    case FRONT:
+      glReadBuffer(GL_FRONT);
+      break;
+    case BACK:
+      glReadBuffer(GL_BACK);
+      break;
+    default:
+      break;
+    }
+  }
+
+  BBox<Vec3r> scene3DBBox() const { return _ModelRootNode->bbox(); }
+
+  inline real znear() const {
+    return _camera->zNear();
+  }
+  
+  inline real zfar() const {
+    return _camera->zFar();
+  }
+
+  inline bool draw3DsceneEnabled() const { return _Draw3DScene; }
+
+  inline bool getRecordFlag() const {return _record;}
+
+  void setCameraState(const float* position, const float* orientation) {
+    _camera->setPosition(Vec(position[0], position[1], position[2]));
+    _camera->setOrientation(Quaternion(orientation[0], orientation[1], orientation[2], orientation[3]));
+  }
+
+  void getCameraState(float* position, float* orientation) const {
+    float* pos = _camera->position();
+    float* orient = _camera->orientation();
+    int i;
+    for(i=0;i<3;++i){
+      position[i] = pos[i];
+    }
+    for(i=0;i<4;++i){
+      orientation[i] = orient[i];
+    }
+  }
+
+  void saveCameraState() {
+    getCameraState(_cameraPosition, _cameraOrientation);
+    _cameraStateSaved = true;
+  }
+
+  void setUpdateMode(bool b) {
+    _enableUpdateSilhouettes = b;
+  }
+
+  bool getUpdateMode() const {
+    return _enableUpdateSilhouettes;
+  }
+  static void setFrontBufferFlag(bool iBool);
+  static bool getFrontBufferFlag();
+  static void setBackBufferFlag(bool iBool);
+  static bool getBackBufferFlag();
+
+protected:
+  virtual void   init();
+  virtual void    draw();
+
+  /*! Loads an envmap */
+  void LoadEnvMap(const char *filename);
+
+public:
+  /*! Core scene drawing */
+  void            DrawScene(SceneVisitor *iRenderer);
+
+  /*! 2D Scene Drawing */
+  void            Draw2DScene(SceneVisitor *iRenderer);
+
+  /*! Draws scene silhouettes in real time */
+  void            DrawSilhouette();
+  
+  /*! Draws the Scene in lines style */
+  //  void            DrawLines();
+  //  /*! Draws the scene in surfacic style */
+  //  void            DrawSurfacic();
+  //  /*! Draws the scene as a depth buffer image */
+  //  void            DrawDepthBuffer();
+
+  GLRenderer* glRenderer() {return _pGLRenderer;}
+
+protected:
+
+
+  //QString shortcutBindingsString() const;
+
+  /*! fabs or abs */
+  inline int rabs(int x) {return abs(x);}
+  inline real rabs(real x) {return fabs(x);}
+
+  
+protected:
+  float _Fovy;
+  //float _SceneDepth;
+  //BBox<Vec3f> _BBox;
+  
+  RenderStyle _RenderStyle;
+
+  //The root node container
+  NodeGroup        _RootNode;
+  NodeDrawingStyle *_ModelRootNode;
+  NodeDrawingStyle *_SilhouetteRootNode;
+  NodeDrawingStyle *_DebugRootNode;
+  
+  bool _silhouette;
+  bool _fedges;
+  bool _debug;
+  bool _selection_mode;
+
+  //a Universal light:
+  NodeGroup _Light;
+
+  real _minBBox;
+  real _maxBBox;
+  real _maxAbs;
+
+  real _minAbs;
+  bool _drawBBox;
+
+  // OpenGL Renderer
+  GLRenderer *_pGLRenderer;
+  GLSelectRenderer *_pSelectRenderer;
+  GLBBoxRenderer *_pBBoxRenderer;
+  GLMonoColorRenderer *_pMonoColorRenderer;
+  GLDebugRenderer *_pDebugRenderer;
+  
+  QMainWindow *_pMainWindow;
+
+  Chronometer _Chrono;
+
+  // 2D Scene
+  bool _Draw2DScene;
+  bool _Draw3DScene;  NodeGroup _p2DNode;
+  //NodeDrawingStyle *_pFENode; // Feature edges node
+  //NodeDrawingStyle *_pVisibleSilhouetteNode;
+  NodeDrawingStyle *_p2DSelectionNode;
+
+  // EnvMap
+  bool _drawEnvMap;
+  int _currentEnvMap;
+  int _maxId;
+  int _blendFunc;
+
+  // Each time we compute the view map, the camera state is 
+  // saved in order to be able to restore it later
+  bool  _cameraStateSaved;
+  float _cameraPosition[3];
+  float _cameraOrientation[4];
+
+  // interactive silhouette update
+  bool _enableUpdateSilhouettes;
+  //capture movie
+  bool _captureMovie;
+  // 2D drawing buffers
+  static bool _frontBufferFlag;
+  static bool _backBufferFlag;
+
+  bool _record;
+
+
+real _width, _height;
+Vec _min,_max;
+string stateFileName_;
+};
+
+#endif // ARTGLWIDGET_H
diff --git a/source/blender/freestyle/intern/app_blender/Controller.cpp b/source/blender/freestyle/intern/app_blender/Controller.cpp
new file mode 100755 (executable)
index 0000000..edc1b7f
--- /dev/null
@@ -0,0 +1,1050 @@
+
+//
+//  Copyright (C) : Please refer to the COPYRIGHT file distributed 
+//   with this source distribution. 
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// Must be included before any QT header, because of moc
+#include "../system/PythonInterpreter.h"
+
+#include <string>
+#include <fstream>
+#include <float.h>
+
+#include "AppGLWidget.h"
+#include "AppCanvas.h"
+#include "AppConfig.h"
+
+
+#include "../system/StringUtils.h"
+#include "../scene_graph/MaxFileLoader.h"
+#include "../scene_graph/NodeShape.h"
+#include "../scene_graph/NodeTransform.h"
+#include "../scene_graph/NodeDrawingStyle.h"
+#include "../winged_edge/WingedEdgeBuilder.h"
+#include "../winged_edge/WEdge.h"
+#include "../scene_graph/VertexRep.h"
+#include "../winged_edge/WXEdgeBuilder.h"
+#include "../scene_graph/ScenePrettyPrinter.h"
+#include "../winged_edge/WFillGrid.h"
+
+#include "../view_map/ViewMapTesselator.h"
+#include "../stroke/StrokeTesselator.h"
+#include "../view_map/ViewMapIO.h"
+#include "Controller.h"
+#include "../view_map/ViewMap.h"
+#include "../winged_edge/Curvature.h"
+//#include "QGLBasicWidget.h"
+//#include <qimage.h>
+#include "../image/Image.h"
+#include "../view_map/SteerableViewMap.h"
+#include "../stroke/PSStrokeRenderer.h"
+#include "../stroke/TextStrokeRenderer.h"
+#include "../stroke/StyleModule.h"
+
+#ifndef WIN32
+//# include "GLXOffscreenBuffer.h"
+//# include "GLXOffscreenBuffer.h"
+#endif
+
+#include "../system/StringUtils.h"
+
+
+Controller::Controller()
+{
+  const string sep(Config::DIR_SEP.c_str());
+  const string filename = Config::Path::getInstance()->getHomeDir() + sep +
+    Config::OPTIONS_DIR + sep + Config::OPTIONS_CURRENT_DIRS_FILE;
+  //_current_dirs = new ConfigIO(filename, Config::APPLICATION_NAME + "CurrentDirs", true);
+
+  _RootNode = new NodeGroup;
+  _RootNode->addRef();
+  
+  _SilhouetteNode = NULL;
+  //_ProjectedSilhouette = NULL;
+  //_VisibleProjectedSilhouette = NULL;
+  
+  _DebugNode = new NodeGroup;
+  _DebugNode->addRef();
+
+  _winged_edge = NULL;
+  
+  _pView = NULL;
+
+  _edgeTesselationNature = (Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE);
+
+  _SceneNumFaces = 0;
+  _minEdgeSize = DBL_MAX;
+  _bboxDiag = 0;
+  
+  _ViewMap = 0;
+
+  _Canvas = 0;
+
+  _VisibilityAlgo = ViewMapBuilder::ray_casting;
+  //_VisibilityAlgo = ViewMapBuilder::ray_casting_fast;
+
+  _Canvas = new AppCanvas;
+
+  _inter = new PythonInterpreter;
+  _EnableQI = true;
+  _ComputeRidges = true;
+  _ComputeSteerableViewMap = false;
+  _ComputeSuggestive = true;
+  _sphereRadius = 1.0;
+}
+
+Controller::~Controller()
+{
+  if(NULL != _RootNode)
+    {
+      int ref = _RootNode->destroy();
+      if(0 == ref)
+       delete _RootNode;
+    }
+  
+  if(NULL != _SilhouetteNode)
+    {
+      int ref = _SilhouetteNode->destroy();
+      if(0 == ref)
+       delete _SilhouetteNode;
+    }
+  
+  if(NULL != _DebugNode)
+    {
+      int ref = _DebugNode->destroy();
+      if(0 == ref)
+       delete _DebugNode;
+    }
+
+  if(_winged_edge) {
+    delete _winged_edge;
+    _winged_edge = NULL;
+  }
+
+  if(0 != _ViewMap)
+    {
+      delete _ViewMap;
+      _ViewMap = 0;
+    }
+
+  if(0 != _Canvas)
+    {
+      delete _Canvas;
+      _Canvas = 0;
+    }
+
+  if (_inter) {
+    delete _inter;
+    _inter = NULL;
+  }
+
+  //delete _current_dirs;
+}
+
+void Controller::SetView(AppGLWidget *iView)
+{
+  if(NULL == iView)
+    return;
+  
+  _pView = iView;
+  _Canvas->SetViewer(_pView);
+}
+
+
+int Controller::Load3DSFile(const char *iFileName)
+{
+  if (_pView)
+    _pView->setUpdateMode(false);
+  
+  MaxFileLoader loader3DS(iFileName);
+  //_RootNode->AddChild(BuildSceneTest());
+  
+  _Chrono.start();
+  
+  NodeGroup *maxScene = loader3DS.Load();
+
+  if (maxScene == NULL) {
+    return 1;
+  }
+
+  printf("Mesh cleaning    : %lf\n", _Chrono.stop());
+  _SceneNumFaces += loader3DS.numFacesRead();
+
+  if(loader3DS.minEdgeSize() < _minEdgeSize)
+    {
+      _minEdgeSize = loader3DS.minEdgeSize();
+      _EPSILON = _minEdgeSize*1e-6;
+      if(_EPSILON < DBL_MIN)
+       _EPSILON = 0.0;
+    }
+
+  cout << "Epsilon computed : " << _EPSILON << endl;
+
+  // DEBUG
+//   ScenePrettyPrinter spp;
+//   maxScene->accept(spp);
+
+  _RootNode->AddChild(maxScene);
+  _RootNode->UpdateBBox(); // FIXME: Correct that by making a Renderer to compute the bbox
+
+  _pView->SetModel(_RootNode);
+  _pView->FitBBox();
+
+  _Chrono.start();
+
+  
+  WXEdgeBuilder wx_builder;
+  maxScene->accept(wx_builder);
+  _winged_edge = wx_builder.getWingedEdge();
+
+  printf("WEdge building   : %lf\n", _Chrono.stop());
+
+ _Chrono.start();
+
+  _Grid.clear();
+  Vec3r size;
+  for(unsigned int i=0; i<3; i++)
+    {
+      size[i] = fabs(_RootNode->bbox().getMax()[i] - _RootNode->bbox().getMin()[i]);
+      size[i] += size[i]/10.0; // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections
+      if(size[i]==0){
+          cout << "Warning: the bbox size is 0 in dimension "<<i<<endl;
+      }
+    }
+  _Grid.configure(Vec3r(_RootNode->bbox().getMin() - size / 20.0), size,
+                 _SceneNumFaces);
+
+  // Fill in the grid:
+  WFillGrid fillGridRenderer(&_Grid, _winged_edge);
+  fillGridRenderer.fillGrid();
+
+  printf("Grid building    : %lf\n", _Chrono.stop());
+  
+  // DEBUG
+//   _Grid.displayDebug();
+   
+  _pView->SetDebug(_DebugNode);
+
+  //delete stuff
+  //  if(0 != ws_builder)
+  //    {
+  //      delete ws_builder;
+  //      ws_builder = 0;
+  //    }
+  _pView->updateGL();
+  
+
+       //soc QFileInfo qfi(iFileName);
+       //soc string basename((const char*)qfi.fileName().toAscii().data());
+       char cleaned[FILE_MAX];
+       BLI_strncpy(cleaned, iFileName, FILE_MAX);
+       BLI_cleanup_file(NULL, cleaned);
+       string basename = StringUtils::toAscii( string(cleaned) );
+
+  _ListOfModels.push_back(basename);
+
+  cout << "Triangles nb     : " << _SceneNumFaces << endl;
+  _bboxDiag = (_RootNode->bbox().getMax()-_RootNode->bbox().getMin()).norm();
+  cout << "Bounding Box     : " << _bboxDiag << endl;
+  return 0;
+}
+
+void Controller::CloseFile()
+{
+  WShape::SetCurrentId(0);
+  _pView->DetachModel();
+  _ListOfModels.clear();
+  if(NULL != _RootNode)
+    {
+      int ref = _RootNode->destroy();
+      if(0 == ref)
+       _RootNode->addRef();
+    
+      _RootNode->clearBBox();
+    }
+  
+  _pView->DetachSilhouette();
+  if (NULL != _SilhouetteNode)
+    {
+      int ref = _SilhouetteNode->destroy();
+      if(0 == ref)
+       {
+         delete _SilhouetteNode;
+         _SilhouetteNode = NULL;
+       }
+    }
+  //  if(NULL != _ProjectedSilhouette)
+  //    {
+  //      int ref = _ProjectedSilhouette->destroy();
+  //      if(0 == ref)
+  //   {
+  //     delete _ProjectedSilhouette;
+  //     _ProjectedSilhouette = NULL;
+  //   }
+  //    }
+  //  if(NULL != _VisibleProjectedSilhouette)
+  //    {
+  //      int ref = _VisibleProjectedSilhouette->destroy();
+  //      if(0 == ref)
+  //   {
+  //     delete _VisibleProjectedSilhouette;
+  //     _VisibleProjectedSilhouette = NULL;
+  //   }
+  //  }
+  
+  _pView->DetachDebug();
+  if(NULL != _DebugNode)
+    {
+      int ref = _DebugNode->destroy();
+      if(0 == ref)
+       _DebugNode->addRef();
+    }
+  
+  if(_winged_edge) {
+    delete _winged_edge;
+    _winged_edge = NULL;
+  }
+
+  // We deallocate the memory:
+  if(NULL != _ViewMap)
+    {
+      delete _ViewMap;
+      _ViewMap = 0;
+    }
+
+  // clears the canvas
+  _Canvas->Erase();
+
+  // clears the grid
+  _Grid.clear();
+  _SceneNumFaces = 0;
+  _minEdgeSize = DBL_MAX;
+  //  _pView2D->DetachScene();
+  //  if(NULL != _SRoot)
+  //  {
+  //    int ref = _SRoot->destroy();
+  //    if(0 == ref)
+  //    {
+  //      //_SRoot->addRef();
+  //      delete _SRoot;
+  //      _SRoot = NULL;
+  //    }
+  //  }
+}
+
+//  static const streamsize buffer_size = 512 * 1024;
+
+void Controller::SaveViewMapFile(const char *oFileName)
+{
+  if (!_ViewMap)
+    return;
+
+  ofstream ofs(oFileName, ios::binary);
+  if (!ofs.is_open()) {
+    cerr << "Error: Cannot save this file" << endl;
+    return;
+  }
+//    char buffer[buffer_size];
+//  #if defined(__GNUC__) && (__GNUC__ < 3)
+//    ofs.rdbuf()->setbuf(buffer, buffer_size);
+//  # else
+//    ofs.rdbuf()->pubsetbuf(buffer, buffer_size);
+//  #endif
+  _Chrono.start();
+
+  ofs << Config::VIEWMAP_MAGIC << endl << Config::VIEWMAP_VERSION << endl;
+
+  // Write the models filenames
+  ofs << _ListOfModels.size() << endl;
+  for (vector<string>::const_iterator i = _ListOfModels.begin(); i != _ListOfModels.end(); i++)
+    ofs << *i << "\n";
+
+  // Save the camera position
+  float position[3];
+  float orientation[4];
+  _pView->getCameraState(position, orientation);
+  ofs.write((char*)position, 3 * sizeof(*position));
+  ofs.write((char*)orientation, 4 * sizeof(*orientation));
+
+  // Write ViewMap
+  if (ViewMapIO::save(ofs, _ViewMap, 0)) {
+    _Chrono.stop();
+    cerr << "Error: Cannot save this file" << endl;
+    return;
+  }
+
+  real d = _Chrono.stop();
+  cout << "ViewMap saving   : " << d << endl;
+}
+
+void Controller::LoadViewMapFile(const char *iFileName, bool only_camera)
+{
+  ifstream ifs(iFileName, ios::binary);
+  if (!ifs.is_open()) {
+    cerr << "Error: Cannot load this file" << endl;
+    return;
+  }
+//    char buffer[buffer_size];
+//  #if defined(__GNUC__) && (__GNUC__ < 3)
+//    ifs.rdbuf()->setbuf(buffer, buffer_size);
+//  # else
+//    ifs.rdbuf()->pubsetbuf(buffer, buffer_size);
+//  #endif
+
+  // Test File Magic and version
+  char tmp_buffer[256];
+  string test;
+  
+  ifs.getline(tmp_buffer, 255);
+  test = tmp_buffer;
+  if (test != Config::VIEWMAP_MAGIC) {
+    cerr << "Error: This is not a valid ." << Config::VIEWMAP_EXTENSION << " file" << endl;
+    return;
+  }
+  ifs.getline(tmp_buffer, 255);
+  test = tmp_buffer;
+  if (test != Config::VIEWMAP_VERSION && !only_camera) {
+    cerr << "Error: This version of the ." << Config::VIEWMAP_EXTENSION << " file format is no longer supported" << endl;
+    return;
+  }
+
+  // Read the models filenames and open them (if not already done)
+  string tmp;
+  vector<string> tmp_vec;
+  unsigned models_nb, i;
+
+  ifs.getline(tmp_buffer, 255);
+  models_nb = atoi(tmp_buffer);
+  for (i = 0; i < models_nb; i++) {
+    ifs.getline(tmp_buffer, 255);
+    tmp = tmp_buffer;
+    tmp_vec.push_back(tmp);
+  }
+  if (_ListOfModels != tmp_vec && !only_camera) {
+    CloseFile();
+    vector<string> pathnames;
+    int err = 0;
+    for (vector<string>::const_iterator i = tmp_vec.begin(); i != tmp_vec.end(); i++)
+      {
+       pathnames.clear();
+       StringUtils::getPathName(ViewMapIO::Options::getModelsPath(), *i, pathnames);
+       for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++)
+         if (!(err = Load3DSFile(j->c_str())))
+           break;
+       if (err) {
+         cerr << "Error: cannot find model \"" << *i << "\" - check the path in the Options" << endl;
+         return;
+       }
+      }
+  }
+
+  // Set the camera position
+  float position[3];
+  float orientation[4];
+  ifs.read((char*)position, 3 * sizeof(*position));
+  ifs.read((char*)orientation, 4 * sizeof(*orientation));
+  _pView->setCameraState(position, orientation);
+  _pView->saveCameraState();
+
+  if (only_camera) {
+    return;
+  }
+
+  // Reset ViewMap
+  if(NULL != _ViewMap)
+    {
+      delete _ViewMap;
+      _ViewMap = 0;
+    }
+  _pView->DetachSilhouette();
+  if (NULL != _SilhouetteNode)
+    {
+      int ref = _SilhouetteNode->destroy();
+      if(0 == ref)
+       delete _SilhouetteNode;
+    }
+  //  if(NULL != _ProjectedSilhouette)
+  //    {
+  //      int ref = _ProjectedSilhouette->destroy();
+  //      if(0 == ref)
+  //   delete _ProjectedSilhouette;
+  //    }
+  //  if(NULL != _VisibleProjectedSilhouette)
+  //    {
+  //      int ref = _VisibleProjectedSilhouette->destroy();
+  //      if(0 == ref)
+  //   {
+  //     delete _VisibleProjectedSilhouette;
+  //     _VisibleProjectedSilhouette = 0;
+  //   }
+   // }
+  _ViewMap = new ViewMap();
+
+  // Read ViewMap
+  _Chrono.start();
+  if (ViewMapIO::load(ifs, _ViewMap, 0)) {
+    _Chrono.stop();
+
+    cerr << "Error: This is not a valid ." << Config::VIEWMAP_EXTENSION << " file" << endl;
+    return;
+  }
+
+  // Update display
+  ViewMapTesselator3D sTesselator3d;
+  //ViewMapTesselator2D sTesselator2d;
+  //sTesselator2d.SetNature(_edgeTesselationNature);
+  sTesselator3d.SetNature(_edgeTesselationNature);
+  
+  // Tesselate the 3D edges:
+  _SilhouetteNode = sTesselator3d.Tesselate(_ViewMap);
+  _SilhouetteNode->addRef();
+  
+  // Tesselate 2D edges
+  //  _ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap);
+  //  _ProjectedSilhouette->addRef();
+  //  
+  _pView->AddSilhouette(_SilhouetteNode);
+  //_pView->Add2DSilhouette(_ProjectedSilhouette);
+
+  // Update options window
+  //_pOptionsWindow->updateViewMapFormat();
+
+  real d = _Chrono.stop();
+  cout << "ViewMap loading  : " << d << endl;
+
+  // Compute the Directional ViewMap:
+  if(_ComputeSteerableViewMap){
+    ComputeSteerableViewMap();
+  }
+
+  // Reset Style modules modification flags
+  resetModified(true);
+}
+
+void Controller::ComputeViewMap()
+{
+
+  if (!_ListOfModels.size())
+    return;
+  
+  if(NULL != _ViewMap)
+    {
+      delete _ViewMap;
+      _ViewMap = 0;
+    }
+
+  _pView->DetachDebug();
+  if(NULL != _DebugNode)
+    {
+      int ref = _DebugNode->destroy();
+      if(0 == ref)
+       _DebugNode->addRef();
+    }
+  
+
+  _pView->DetachSilhouette();
+  if (NULL != _SilhouetteNode)
+    {
+      int ref = _SilhouetteNode->destroy();
+      if(0 == ref)
+       delete _SilhouetteNode;
+    }
+  //  if(NULL != _ProjectedSilhouette)
+  //    {
+  //      int ref = _ProjectedSilhouette->destroy();
+  //      if(0 == ref)
+  //   delete _ProjectedSilhouette;
+  //    }
+  //  if(NULL != _VisibleProjectedSilhouette)
+  //    {
+  //      int ref = _VisibleProjectedSilhouette->destroy();
+  //      if(0 == ref)
+  //   {
+  //     delete _VisibleProjectedSilhouette;
+  //     _VisibleProjectedSilhouette = 0;
+  //   }
+  //  }
+  
+  // retrieve the 3D viewpoint and transformations information
+  //----------------------------------------------------------
+  // Save the viewpoint context at the view level in order 
+  // to be able to restore it later:
+  _pView->saveCameraState();
+
+  // Restore the context of view:
+  // we need to perform all these operations while the 
+  // 3D context is on.
+  _pView->Set3DContext();
+  float src[3] = { 0, 0, 0 };
+  float vp_tmp[3] = { 0, 0, 0 };
+  _pView->_camera->getWorldCoordinatesOf(src, vp_tmp);
+  Vec3r vp(vp_tmp[0], vp_tmp[1], vp_tmp[2]);
+
+  real mv[4][4];
+  _pView->RetriveModelViewMatrix((real *)mv);
+  // retrieve the projection matrix:
+  real proj[4][4];
+  _pView->RetrieveProjectionMatrix((real *)proj);
+  int viewport[4];
+  _pView->RetrieveViewport(viewport);  
+  real focalLength = _pView->GetFocalLength();
+
+  // Flag the WXEdge structure for silhouette edge detection:
+  //----------------------------------------------------------
+
+  _Chrono.start();
+  edgeDetector.SetViewpoint(Vec3r(vp));
+  edgeDetector.enableRidgesAndValleysFlag(_ComputeRidges);
+  edgeDetector.enableSuggestiveContours(_ComputeSuggestive);
+  edgeDetector.setSphereRadius(_sphereRadius);
+  edgeDetector.setSuggestiveContourKrDerivativeEpsilon(_suggestiveContourKrDerivativeEpsilon);
+  edgeDetector.processShapes(*_winged_edge);
+
+  real duration = _Chrono.stop();
+  printf("Feature lines    : %lf\n", duration);
+
+  // Builds the view map structure from the flagged WSEdge structure:
+  //----------------------------------------------------------
+  ViewMapBuilder vmBuilder;
+  vmBuilder.SetEnableQI(_EnableQI);
+  vmBuilder.SetViewpoint(Vec3r(vp));
+  
+  vmBuilder.SetTransform(mv, proj, viewport, focalLength, _pView->GetAspect(), _pView->GetFovyRadian());
+  vmBuilder.SetFrustum(_pView->znear(), _pView->zfar());
+  
+  vmBuilder.SetGrid(&_Grid);
+  
+  // Builds a tesselated form of the silhouette for display purpose:
+  //---------------------------------------------------------------
+  ViewMapTesselator3D sTesselator3d;
+  //ViewMapTesselator2D sTesselator2d;
+  //sTesselator2d.SetNature(_edgeTesselationNature);
+  sTesselator3d.SetNature(_edgeTesselationNature);
+    
+  _Chrono.start();
+  // Build View Map
+  _ViewMap = vmBuilder.BuildViewMap(*_winged_edge, _VisibilityAlgo, _EPSILON);
+  _ViewMap->setScene3dBBox(_RootNode->bbox());
+  
+  //Tesselate the 3D edges:
+  _SilhouetteNode = sTesselator3d.Tesselate(_ViewMap);
+  _SilhouetteNode->addRef();
+  
+  // Tesselate 2D edges
+  //  _ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap);
+  //  _ProjectedSilhouette->addRef();
+  
+  duration = _Chrono.stop();
+  printf("ViewMap building : %lf\n", duration);
+
+  
+  _pView->AddSilhouette(_SilhouetteNode);
+  //_pView->AddSilhouette(_WRoot);
+  //_pView->Add2DSilhouette(_ProjectedSilhouette);
+  //_pView->Add2DVisibleSilhouette(_VisibleProjectedSilhouette);  
+  _pView->AddDebug(_DebugNode);
+
+  // Draw the steerable density map:
+  //--------------------------------
+  if(_ComputeSteerableViewMap){
+    ComputeSteerableViewMap();
+  }
+  // Reset Style modules modification flags
+  resetModified(true);
+}
+
+void Controller::ComputeSteerableViewMap(){
+//soc
+  // if((!_Canvas) || (!_ViewMap))
+  //   return;
+  //   
+  // // Build 4 nodes containing the edges in the 4 directions
+  // NodeGroup *ng[Canvas::NB_STEERABLE_VIEWMAP];
+  // unsigned i;
+  // real c = 32.f/255.f; // see SteerableViewMap::readSteerableViewMapPixel() for information about this 32.
+  // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){
+  //   ng[i] = new NodeGroup;
+  // }
+  // NodeShape *completeNS = new NodeShape;
+  // completeNS->material().SetDiffuse(c,c,c,1);
+  // ng[Canvas::NB_STEERABLE_VIEWMAP-1]->AddChild(completeNS);
+  // SteerableViewMap * svm = _Canvas->getSteerableViewMap();
+  // svm->Reset();
+  // 
+  // ViewMap::fedges_container& fedges = _ViewMap->FEdges();
+  // LineRep * fRep;
+  // NodeShape *ns;
+  // for(ViewMap::fedges_container::iterator f=fedges.begin(), fend=fedges.end();
+  // f!=fend;
+  // ++f){
+  //   if((*f)->viewedge()->qi() != 0)
+  //     continue;
+  //   fRep = new LineRep((*f)->vertexA()->point2d(),(*f)->vertexB()->point2d()) ;
+  //   completeNS->AddRep(fRep); // add to the complete map anyway
+  //   double *oweights = svm->AddFEdge(*f);
+  //   for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP-1; ++i){
+  //     ns = new NodeShape;
+  //     double wc = oweights[i]*c;
+  //     if(oweights[i] == 0)
+  //       continue;
+  //     ns->material().SetDiffuse(wc, wc, wc, 1);
+  //     ns->AddRep(fRep);
+  //     ng[i]->AddChild(ns);
+  //   }
+  // }
+  // 
+  // GrayImage *img[Canvas::NB_STEERABLE_VIEWMAP];
+  // //#ifdef WIN32
+  // QGLBasicWidget offscreenBuffer(_pView, "SteerableViewMap", _pView->width(), _pView->height()); 
+  // QPixmap pm;
+  // QImage qimg;
+  // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){
+  //   offscreenBuffer.AddNode(ng[i]);
+  //   //img[i] = new GrayImage(_pView->width(), _pView->height());
+  //   //offscreenBuffer.readPixels(0,0,_pView->width(), _pView->height(), img[i]->getArray());
+  //   pm = offscreenBuffer.renderPixmap(_pView->width(), _pView->height());
+  // 
+  //   if(pm.isNull())
+  //     cout << "BuildViewMap Warning: couldn't render the steerable ViewMap" << endl;
+  //   //pm.save(QString("steerable")+QString::number(i)+QString(".bmp"), "BMP");
+  //   // FIXME!! Lost of time !
+  //   qimg = pm.toImage();
+  //   // FIXME !! again!
+  //   img[i] = new GrayImage(_pView->width(), _pView->height());
+  //   for(unsigned y=0;y<img[i]->height();++y){
+  //     for(unsigned x=0;x<img[i]->width();++x){
+  //       //img[i]->setPixel(x,y,(float)qGray(qimg.pixel(x,y))/255.f);
+  //       img[i]->setPixel(x,y,(float)qGray(qimg.pixel(x,y)));
+  //       //        float c = qGray(qimg.pixel(x,y));
+  //       //        img[i]->setPixel(x,y,qGray(qimg.pixel(x,y)));
+  //     }
+  //   }
+  //   offscreenBuffer.DetachNode(ng[i]);
+  //   ng[i]->destroy();
+  //   delete ng[i];
+  //   // check
+  //   //    qimg = QImage(_pView->width(), _pView->height(), 32);
+  //   //    for(y=0;y<img[i]->height();++y){
+  //   //      for(unsigned x=0;x<img[i]->width();++x){
+  //   //        float v = img[i]->pixel(x,y);
+  //   //        qimg.setPixel(x,y,qRgb(v,v,v));
+  //   //      }
+  //   //    }
+  //   //    qimg.save(QString("newsteerable")+QString::number(i)+QString(".bmp"), "BMP");
+  // }
+  // 
+  // 
+  // svm->buildImagesPyramids(img,false,0,1.f);
+}
+
+void Controller::saveSteerableViewMapImages(){
+  SteerableViewMap * svm = _Canvas->getSteerableViewMap();
+  if(!svm){
+    cerr << "the Steerable ViewMap has not been computed yet" << endl;
+    return;
+  }
+  svm->saveSteerableViewMap();
+}
+
+void Controller::toggleVisibilityAlgo() 
+{
+  if(_VisibilityAlgo == ViewMapBuilder::ray_casting) {
+    _VisibilityAlgo = ViewMapBuilder::ray_casting_fast;
+  }
+  else if (_VisibilityAlgo == ViewMapBuilder::ray_casting_fast) {
+    _VisibilityAlgo = ViewMapBuilder::ray_casting_very_fast;
+  }
+  else {
+    _VisibilityAlgo = ViewMapBuilder::ray_casting;
+  }
+}
+
+void Controller::setQuantitativeInvisibility(bool iBool)
+{
+  _EnableQI = iBool;
+}
+
+bool Controller::getQuantitativeInvisibility() const
+{
+  return _EnableQI;
+}
+
+void Controller::setComputeRidgesAndValleysFlag(bool iBool){
+  _ComputeRidges = iBool;
+}
+
+bool Controller::getComputeRidgesAndValleysFlag() const {
+  return _ComputeRidges;
+}
+void Controller::setComputeSuggestiveContoursFlag(bool b){
+  _ComputeSuggestive = b;
+}
+  
+bool Controller::getComputeSuggestiveContoursFlag() const {
+  return _ComputeSuggestive;
+}
+void Controller::setComputeSteerableViewMapFlag(bool iBool){
+  _ComputeSteerableViewMap = iBool;
+}
+
+bool Controller::getComputeSteerableViewMapFlag() const {
+  return _ComputeSteerableViewMap;
+}
+void Controller::setFrontBufferFlag(bool iBool)
+{
+  AppGLWidget::setFrontBufferFlag(iBool);
+}
+
+bool Controller::getFrontBufferFlag() const
+{
+  return AppGLWidget::getFrontBufferFlag();
+}
+
+void Controller::setBackBufferFlag(bool iBool)
+{
+  AppGLWidget::setBackBufferFlag(iBool);
+}
+
+bool Controller::getBackBufferFlag() const
+{
+  return AppGLWidget::getBackBufferFlag();
+}
+
+void Controller::DrawStrokes()
+{
+  if(_ViewMap == 0)
+    return;
+
+  _Chrono.start();
+  _Canvas->Draw();
+  real d = _Chrono.stop();
+  cout << "Strokes drawing  : " << d << endl;
+  resetModified();
+}
+
+void Controller::InsertStyleModule(unsigned index, const char *iFileName)
+{
+  // QFileInfo fi(iFileName);
+  // string ext = fi.suffix();
+  // if (ext != "py") {
+  //   cerr << "Error: Cannot load \"" << fi.fileName().toAscii().data()
+  //    << "\", unknown extension" << endl;
+  //   return;
+  // }
+
+       if( !BLI_testextensie(iFileName, ".py") ) {
+               cerr << "Error: Cannot load \"" << StringUtils::toAscii( string(iFileName) )
+                 << "\", unknown extension" << endl;
+                 return;
+       }
+
+  StyleModule* sm = new StyleModule(iFileName, _inter);
+  _Canvas->InsertStyleModule(index, sm);
+  
+}
+
+void Controller::AddStyleModule(const char *iFileName)
+{
+  //_pStyleWindow->Add(iFileName);
+}
+
+void Controller::RemoveStyleModule(unsigned index)
+{
+  _Canvas->RemoveStyleModule(index);
+}
+
+void Controller::Clear()
+{
+  _Canvas->Clear();
+}
+
+void Controller::ReloadStyleModule(unsigned index, const char * iFileName)
+{
+  StyleModule* sm = new StyleModule(iFileName, _inter);
+  _Canvas->ReplaceStyleModule(index, sm);
+}
+
+void Controller::SwapStyleModules(unsigned i1, unsigned i2)
+{
+  _Canvas->SwapStyleModules(i1, i2);
+}
+
+
+void Controller::toggleLayer(unsigned index, bool iDisplay)
+{
+  _Canvas->SetVisible(index, iDisplay);
+  _pView->updateGL();
+}
+
+void Controller::setModified(unsigned index, bool iMod)
+{
+  //_pStyleWindow->setModified(index, iMod);
+  _Canvas->setModified(index, iMod);
+  updateCausalStyleModules(index + 1);
+}
+
+void Controller::updateCausalStyleModules(unsigned index) {
+  vector<unsigned> vec;
+  _Canvas->causalStyleModules(vec, index);
+  for (vector<unsigned>::const_iterator it = vec.begin(); it != vec.end(); it++) {
+    //_pStyleWindow->setModified(*it, true);
+    _Canvas->setModified(*it, true);
+  }
+}
+
+void Controller::saveSnapshot(bool b) {
+ _pView->saveSnapshot(b);
+}
+
+void Controller::resetModified(bool iMod)
+{
+  //_pStyleWindow->resetModified(iMod);
+  _Canvas->resetModified(iMod);
+}
+
+FEdge* Controller::SelectFEdge(real x, real y)
+{
+  if (!_ViewMap)
+    return NULL;
+
+  FEdge *fedge = (FEdge*)_ViewMap->GetClosestFEdge(x,y);
+  //ViewEdge *selection = fedge->viewedge();
+  _pView->SetSelectedFEdge(fedge);
+  _Canvas->SetSelectedFEdge(fedge);
+  return fedge;
+}
+
+ViewEdge* Controller::SelectViewEdge(real x, real y)
+{
+  if (!_ViewMap)
+    return NULL;
+
+  FEdge *fedge = (FEdge*)_ViewMap->GetClosestFEdge(x,y);
+  ViewEdge *selection = fedge->viewedge();
+  _pView->SetSelectedFEdge(fedge);
+  _Canvas->SetSelectedFEdge(fedge);
+  return selection;
+}
+
+NodeGroup * Controller::BuildRep(vector<ViewEdge*>::iterator vedges_begin, 
+                                       vector<ViewEdge*>::iterator vedges_end)
+{
+  ViewMapTesselator2D tesselator2D;
+  Material mat;
+  mat.SetDiffuse(1,1,0.3,1);
+  tesselator2D.SetMaterial(mat);
+
+  return (tesselator2D.Tesselate(vedges_begin, vedges_end));
+}
+
+void Controller::toggleEdgeTesselationNature(Nature::EdgeNature iNature)
+{
+  _edgeTesselationNature ^= (iNature);
+  ComputeViewMap();
+}
+
+void           Controller::setModelsDir(const string& dir) {
+  //_current_dirs->setValue("models/dir", dir);
+}
+
+string         Controller::getModelsDir() const {
+  string dir = ".";
+  //_current_dirs->getValue("models/dir", dir);
+  return dir;
+}
+
+void           Controller::setModulesDir(const string& dir) {
+  //_current_dirs->setValue("modules/dir", dir);
+}
+
+string         Controller::getModulesDir() const {
+  string dir = ".";
+  //_current_dirs->getValue("modules/dir", dir);
+  return dir;
+}
+
+void           Controller::setPapersDir(const string& dir) {
+  //_current_dirs->setValue("papers/dir", dir);
+}
+
+string         Controller::getPapersDir() const {
+  string dir = Config::Path::getInstance()->getPapersDir();
+  //_current_dirs->getValue("papers/dir", dir);
+  return dir;
+}
+
+void           Controller::setHelpIndex(const string& index) {
+  _help_index = index;
+}
+
+string         Controller::getHelpIndex() const {
+  return _help_index;
+}
+
+void           Controller::setBrowserCmd(const string& cmd) {
+  _browser_cmd = cmd;
+}
+
+string         Controller::getBrowserCmd() const {
+  return _browser_cmd;
+}
+
+void           Controller::resetInterpreter() {
+  if (_inter)
+    _inter->reset();
+}
+
+
+void Controller::displayDensityCurves(int x, int y){
+  SteerableViewMap * svm = _Canvas->getSteerableViewMap();
+  if(!svm)
+    return;
+
+  unsigned i,j;
+  typedef vector<Vec3r> densityCurve;
+  vector<densityCurve> curves(svm->getNumberOfOrientations()+1);
+  vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels());
+
+  // collect the curves values
+  unsigned nbCurves = svm->getNumberOfOrientations()+1;
+  unsigned nbPoints = svm->getNumberOfPyramidLevels();
+  if(!nbPoints)
+    return;
+
+  // build the density/nbLevels curves for each orientation
+  for(i=0;i<nbCurves; ++i){
+    for(j=0; j<nbPoints; ++j){
+      curves[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(i, j, x, y), 0));
+    }
+  }
+  // build the density/nbOrientations curves for each level
+  for(i=0;i<nbPoints; ++i){
+    for(j=0; j<nbCurves; ++j){
+      curvesDirection[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(j, i, x, y), 0));
+    }
+  }
+
+  // display the curves
+  // for(i=0; i<nbCurves; ++i)
+  //     _pDensityCurvesWindow->SetOrientationCurve(i, Vec2d(0,0), Vec2d(nbPoints, 1), curves[i], "scale", "density");
+  //   for(i=1; i<=8; ++i)
+  //     _pDensityCurvesWindow->SetLevelCurve(i, Vec2d(0,0), Vec2d(nbCurves, 1), curvesDirection[i], "orientation", "density");
+  //   _pDensityCurvesWindow->show();
+}
diff --git a/source/blender/freestyle/intern/app_blender/Controller.h b/source/blender/freestyle/intern/app_blender/Controller.h
new file mode 100755 (executable)
index 0000000..55ef196
--- /dev/null
@@ -0,0 +1,213 @@
+//
+//  Filename         : Controller.h
+//  Author           : Stephane Grabli
+//  Purpose          : The spinal tap of the system
+//  Date of creation : 01/07/2002
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//
+//  Copyright (C) : Please refer to the COPYRIGHT file distributed 
+//   with this source distribution. 
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef  CONTROLLER_H
+# define CONTROLLER_H
+
+# include <string>
+//# include "ConfigIO.h"
+# include "../geometry/FastGrid.h"
+# include "../geometry/HashGrid.h"
+# include "../view_map/ViewMapBuilder.h"
+# include "../system/TimeUtils.h"
+# include "../system/Precision.h"
+# include "../system/Interpreter.h"
+# include "../view_map/FEdgeXDetector.h"
+
+class AppGLWidget;
+class NodeGroup;
+class WShape;
+class SShape;
+class ViewMap;
+class ViewEdge;
+class AppCanvas;
+class InteractiveShader;
+class Shader;
+
+class Controller
+{
+public:
+  Controller() ;
+  ~Controller() ;
+  
+  void SetView(AppGLWidget *iView);
+
+  int  Load3DSFile(const char *iFileName);
+  void CloseFile();
+  void LoadViewMapFile(const char *iFileName, bool only_camera = false);
+  void SaveViewMapFile(const char *iFileName);
+  void ComputeViewMap();
+  void ComputeSteerableViewMap();
+  void saveSteerableViewMapImages();
+  void toggleEdgeTesselationNature(Nature::EdgeNature iNature);
+  void DrawStrokes();
+  void SwapStyleModules(unsigned i1, unsigned i2);
+  void InsertStyleModule(unsigned index, const char *iFileName);
+  void AddStyleModule(const char *iFileName);
+  void RemoveStyleModule(unsigned index);
+  void ReloadStyleModule(unsigned index, const char * iFileName);
+  void Clear();
+  void toggleLayer(unsigned index, bool iDisplay);
+  void setModified(unsigned index, bool iMod);
+  void resetModified(bool iMod=false);
+  void updateCausalStyleModules(unsigned index);
+  void saveSnapshot(bool b = false);
+  void displayDensityCurves(int x, int y);
+  
+  ViewEdge * SelectViewEdge(real x, real y);
+  FEdge * SelectFEdge(real x, real y);
+  NodeGroup* BuildRep(vector<ViewEdge*>::iterator vedges_begin, 
+                     vector<ViewEdge*>::iterator vedges_end) ;
+  
+  NodeGroup* debugNode() {return _DebugNode;}
+  AppGLWidget * view() {return _pView;}
+  NodeGroup* debugScene() {return _DebugNode;}
+  Grid& grid() {return _Grid;}
+  
+  void toggleVisibilityAlgo();
+
+  void setQuantitativeInvisibility(bool iBool); // if true, we compute quantitativeInvisibility
+  bool getQuantitativeInvisibility() const;
+
+  void setFrontBufferFlag(bool b);
+  bool getFrontBufferFlag() const;
+  void setBackBufferFlag(bool b);
+  bool getBackBufferFlag() const;
+
+  void setComputeRidgesAndValleysFlag(bool b);
+  bool getComputeRidgesAndValleysFlag() const ;
+  void setComputeSuggestiveContoursFlag(bool b);
+  bool getComputeSuggestiveContoursFlag() const ;
+
+  void setComputeSteerableViewMapFlag(bool iBool);
+  bool getComputeSteerableViewMapFlag() const;
+  void setSphereRadius(real s){_sphereRadius=s;}
+  real getSphereRadius() const {return _sphereRadius;}
+  void setSuggestiveContourKrDerivativeEpsilon(real dkr){_suggestiveContourKrDerivativeEpsilon=dkr;}
+  real getSuggestiveContourKrDerivativeEpsilon() const {return _suggestiveContourKrDerivativeEpsilon;}
+
+  void         setModelsDir(const string& dir);
+  string       getModelsDir() const;
+  void         setModulesDir(const string& dir);
+  string       getModulesDir() const;
+  void         setPapersDir(const string& dir);
+  string       getPapersDir() const;
+  void         setHelpIndex(const string& dir);
+  string       getHelpIndex() const;
+  void         setBrowserCmd(const string& cmd);
+  string       getBrowserCmd() const;
+
+  void resetInterpreter();
+
+private:
+
+  // Main Window:
+  //AppMainWindow *_pMainWindow;
+
+  // List of models currently loaded
+  vector<string> _ListOfModels;
+
+  // Current directories
+  //ConfigIO* _current_dirs;
+
+  //View
+  // 3D
+  AppGLWidget *_pView;
+  
+  // 2D
+  //Viewer2DWindow *_pView2DWindow;
+  //Viewer2D *_pView2D;
+  
+  //Model
+  // Drawing Structure
+  NodeGroup *_RootNode;
+
+  // Winged-Edge structure
+  WingedEdge* _winged_edge;
+  
+  ViewMap * _ViewMap;
+
+  // Silhouette structure:
+  //std::vector<SShape*> _SShapes;
+  //NodeGroup *_SRoot;
+  
+  // Silhouette
+  NodeGroup *_SilhouetteNode;
+  NodeGroup *_ProjectedSilhouette;
+  NodeGroup *_VisibleProjectedSilhouette;
+  
+  // more Debug info
+  NodeGroup *_DebugNode;
+
+  // debug
+  //  NodeUser<ViewMap> *_ViewMapNode; // FIXME
+
+  // Chronometer:
+  Chronometer _Chrono;
+
+  // edges tesselation nature
+  int _edgeTesselationNature;
+
+  FastGrid _Grid;
+  //HashGrid _Grid;
+  
+  unsigned int _SceneNumFaces;
+  real _minEdgeSize;
+  real _EPSILON;
+  real _bboxDiag;
+
+  AppCanvas *_Canvas;
+
+  //AppStyleWindow *_pStyleWindow;
+  //AppOptionsWindow *_pOptionsWindow;
+  //AppDensityCurvesWindow *_pDensityCurvesWindow;
+
+  ViewMapBuilder::visibility_algo      _VisibilityAlgo;
+  
+  // Script Interpreter
+  Interpreter* _inter;
+
+  string       _help_index;
+  string       _browser_cmd;
+
+  bool _EnableQI;
+  bool _ComputeRidges;
+  bool _ComputeSuggestive;
+  real _sphereRadius;
+  real _suggestiveContourKrDerivativeEpsilon;
+
+  bool _ComputeSteerableViewMap;
+
+  FEdgeXDetector edgeDetector;
+};
+
+extern Controller      *g_pController;
+
+#endif // CONTROLLER_H
index b396a0ce6d31ef57c1c12bd716430c7ca47a3f52..716db397e9495497a8b9ac19d53a9b6913c9f6d5 100755 (executable)
@@ -124,7 +124,7 @@ void GLDebugRenderer::renderBitmapString(real x,
   glScalef(textSize/200.0, textSize/200.0, textSize/200.0);
   for (c=string; *c != '\0'; c++) 
   {
-    glutStrokeCharacter(font, *c);
+    //soc glutStrokeCharacter(font, *c);
   }
   glPopMatrix();
 }
index 3870edc2b7527f7cd3021b4c012fc03a5340a9f2..d7f2e5683c50b1688cde509705ad5c2e5159788a 100755 (executable)
@@ -201,6 +201,7 @@ unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{
     return _imagesPyramids[0]->getNumberOfLevels();
   return 0;
 }
+
 void SteerableViewMap::saveSteerableViewMap() const {
   for(unsigned i=0; i<=_nbOrientations; ++i){
     if(_imagesPyramids[i] == 0){
index f9e46b20d9a55bbe3f7af8b106a37cef40a332b8..7d44f82a1d075a96c8527079afc491c3fd5b110f 100644 (file)
@@ -31,4 +31,4 @@ if env['WITH_BF_QUICKTIME']==1:
        incs += ' ' + env['BF_QUICKTIME_INC']
        defs.append('WITH_QUICKTIME')
 
-env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [80, 40] )
+env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player','blender'], priority = [80, 40, -1] )
index 45833695ffe8d088078537ecd7bdabe2be710956..3d1641a2110bb7d43be17a1bca79807003c9a6d2 100644 (file)
@@ -610,6 +610,7 @@ typedef struct Scene {
 /* yafray: renderer flag (not only exclusive to yafray) */
 #define R_INTERN       0
 #define R_YAFRAY       1
+#define R_FREESTYLE    2
 
 /* scemode (int now) */
 #define R_DOSEQ                                0x0001
index db5ad669255bf43b6fcd90a8407625bb4fb329f9..fdc656081460ac3a53a7ecd1adf3bd0630b465d8 100644 (file)
@@ -970,6 +970,8 @@ static int RenderData_setRenderer( BPy_RenderData * self, PyObject * value )
                self->renderContext->renderer = R_INTERN;
        else if( type == R_YAFRAY )
                self->renderContext->renderer = R_YAFRAY;
+       else if( type == R_FREESTYLE )
+               self->renderContext->renderer = R_FREESTYLE;
        else
                return EXPP_ReturnIntError( PyExc_ValueError,
                                "expected constant INTERNAL or YAFRAY" );
@@ -3835,6 +3837,7 @@ PyObject *Render_Init( void )
 
        PyModule_AddIntConstant( submodule, "INTERNAL", R_INTERN );
        PyModule_AddIntConstant( submodule, "YAFRAY", R_YAFRAY );
+       PyModule_AddIntConstant( submodule, "FREESTYLE", R_FREESTYLE );
        PyModule_AddIntConstant( submodule, "AVIRAW", R_AVIRAW );
        PyModule_AddIntConstant( submodule, "AVIJPEG", R_AVIJPEG );
        PyModule_AddIntConstant( submodule, "AVICODEC", R_AVICODEC );
index b1bc9673f23310cbabd9a9de2dbe460ca5b87a29..ce00af8af4391620a700dc197b896cfe9ac328e8 100644 (file)
@@ -7,6 +7,7 @@ sources = env.Glob('intern/source/*.c')
 incs = 'intern/include #/intern/guardedalloc ../blenlib ../makesdna'
 incs += ' extern/include ../blenkernel ../radiosity/extern/include ../imbuf'
 incs += ' ../quicktime ../include ../../kernel/gen_messaging'
+incs += ' ../freestyle'
 
 defs = []
 
index 93282e641d352c776ec20145d02bd0cda0d65689..feccec6461ff930f6707f12393486d22c846117a 100644 (file)
@@ -70,6 +70,9 @@
 
 #endif /* disable yafray */
 
+#include "FST_freestyle.h"
+
+
 /* internal */
 #include "render_types.h"
 #include "renderpipeline.h"
@@ -2192,6 +2195,11 @@ static void do_render_composite_fields_blur_3d(Render *re)
        re->display_draw(re->result, NULL);
 }
 
+static void freestyleRender(Render *re)
+{
+       FRS_execute();
+}
+
 #ifndef DISABLE_YAFRAY
 /* yafray: main yafray render/export call */
 static void yafrayRender(Render *re)
@@ -2286,10 +2294,15 @@ static void do_render_all_options(Render *re)
 #ifndef DISABLE_YAFRAY
                if(re->r.renderer==R_YAFRAY)
                        yafrayRender(re);
+               else if(re->r.renderer==R_FREESTYLE)
+                       freestyleRender(re);
                else
                        do_render_composite_fields_blur_3d(re);
 #else
-               do_render_composite_fields_blur_3d(re);
+               if(re->r.renderer==R_FREESTYLE)
+                       freestyleRender(re);
+               else
+                       do_render_composite_fields_blur_3d(re);
 #endif
        }
        
@@ -2402,7 +2415,7 @@ static int is_rendering_allowed(Render *re)
        }
        
        /* renderer */
-       if(!ELEM(re->r.renderer, R_INTERN, R_YAFRAY)) {
+       if(!ELEM3(re->r.renderer, R_INTERN, R_YAFRAY, R_FREESTYLE)) {
                re->error("Unknown render engine set");
                return 0;
        }
index b295cdd84810b3a6ed41da7c452ed14441072197..e24101786a3cd051b77a5d64295a28b5b552cc9c 100644 (file)
@@ -2180,10 +2180,10 @@ static void render_panel_render(void)
        uiDefBut(block, BUT,B_DORENDER,"RENDER",        369, 164, 191,37, 0, 0, 0, 0, 0, "Render the current frame (F12)");
 #ifndef DISABLE_YAFRAY
        /* yafray: on request, render engine menu is back again, and moved to Render panel */
-       uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1", 
+       uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1|Freestyle %x2", 
                                                                                                369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine");        
 #else
-       uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0", 
+       uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|Freestyle %x1", 
                                                                                                369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine");        
 #endif /* disable yafray */
 
index 7699de4138160b4283ba8b1d4d57bbfc54c0e7b7..4576e149ed2056fc75ee6bf520b33d31bef3fe91 100644 (file)
@@ -645,10 +645,12 @@ static char *renderwin_get_title()
        
        if(BIF_show_render_spare()) {
                if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render (previous)";
+               else if (G.scene->r.renderer==R_FREESTYLE) title = "Freestyle:Render (previous)";
                else title = "Blender:Render (previous)";
        }
        else {
                if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render";
+               else if (G.scene->r.renderer==R_FREESTYLE) title = "Freestyle:Render";
                else title = "Blender:Render";
        }