Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Curioni <maxime.curioni@gmail.com>2008-05-08 23:16:40 +0400
committerMaxime Curioni <maxime.curioni@gmail.com>2008-05-08 23:16:40 +0400
commit64e4a3ec9aed6c8abe095e2cd1fe1552f7cde51c (patch)
tree6c77358bd447b6c2d215324ef48fc12d1f5ae5ca /source/blender/freestyle/intern/app
parentcf2e1e2857cfc5b3c2848c7fc6c9d919ac72fabb (diff)
parent106974a9d2d5caa5188322507980e3d57d2e3517 (diff)
soc-2008-mxcurioni: merged changes to revision 14747, cosmetic changes for source/blender/freestyle
Diffstat (limited to 'source/blender/freestyle/intern/app')
-rwxr-xr-xsource/blender/freestyle/intern/app/AppAboutWindow.cpp36
-rwxr-xr-xsource/blender/freestyle/intern/app/AppAboutWindow.h40
-rwxr-xr-xsource/blender/freestyle/intern/app/AppCanvas.cpp404
-rwxr-xr-xsource/blender/freestyle/intern/app/AppCanvas.h84
-rwxr-xr-xsource/blender/freestyle/intern/app/AppConfig.cpp120
-rwxr-xr-xsource/blender/freestyle/intern/app/AppConfig.h125
-rwxr-xr-xsource/blender/freestyle/intern/app/AppDensityCurvesWindow.cpp65
-rwxr-xr-xsource/blender/freestyle/intern/app/AppDensityCurvesWindow.h85
-rwxr-xr-xsource/blender/freestyle/intern/app/AppGL2DCurvesViewer.cpp152
-rwxr-xr-xsource/blender/freestyle/intern/app/AppGL2DCurvesViewer.h80
-rwxr-xr-xsource/blender/freestyle/intern/app/AppGLWidget.cpp1049
-rwxr-xr-xsource/blender/freestyle/intern/app/AppGLWidget.h526
-rwxr-xr-xsource/blender/freestyle/intern/app/AppInteractiveShaderWindow.cpp119
-rwxr-xr-xsource/blender/freestyle/intern/app/AppInteractiveShaderWindow.h73
-rwxr-xr-xsource/blender/freestyle/intern/app/AppMainWindow.cpp288
-rwxr-xr-xsource/blender/freestyle/intern/app/AppMainWindow.h83
-rwxr-xr-xsource/blender/freestyle/intern/app/AppOptionsWindow.cpp410
-rwxr-xr-xsource/blender/freestyle/intern/app/AppOptionsWindow.h74
-rwxr-xr-xsource/blender/freestyle/intern/app/AppProgressBar.cpp78
-rwxr-xr-xsource/blender/freestyle/intern/app/AppProgressBar.h55
-rwxr-xr-xsource/blender/freestyle/intern/app/AppStyleWindow.cpp366
-rwxr-xr-xsource/blender/freestyle/intern/app/AppStyleWindow.h93
-rwxr-xr-xsource/blender/freestyle/intern/app/ConfigIO.cpp116
-rwxr-xr-xsource/blender/freestyle/intern/app/ConfigIO.h181
-rwxr-xr-xsource/blender/freestyle/intern/app/Controller.cpp1498
-rwxr-xr-xsource/blender/freestyle/intern/app/Controller.h232
-rwxr-xr-xsource/blender/freestyle/intern/app/Main.cpp57
-rwxr-xr-xsource/blender/freestyle/intern/app/QGLBasicWidget.cpp141
-rwxr-xr-xsource/blender/freestyle/intern/app/QGLBasicWidget.h102
-rwxr-xr-xsource/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.cpp155
-rwxr-xr-xsource/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.h57
-rwxr-xr-xsource/blender/freestyle/intern/app/app.pro179
-rwxr-xr-xsource/blender/freestyle/intern/app/appmainwindowbase4.ui237
-rwxr-xr-xsource/blender/freestyle/intern/app/densitycurveswindow4.ui442
-rwxr-xr-xsource/blender/freestyle/intern/app/freestyle.qrc23
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/add.pngbin0 -> 400 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/arrow_down.pngbin0 -> 813 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/arrow_left.pngbin0 -> 776 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/arrow_right.pngbin0 -> 773 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/arrow_up.pngbin0 -> 782 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/clear.pngbin0 -> 1057 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/close.pngbin0 -> 1437 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/edit.pngbin0 -> 896 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/eye0.pngbin0 -> 406 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/eye1.pngbin0 -> 402 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/folder.pngbin0 -> 1015 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/home.pngbin0 -> 1050 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/mod0.pngbin0 -> 910 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/mod1.pngbin0 -> 1051 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/ok.pngbin0 -> 769 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/reload.pngbin0 -> 1113 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/remove.pngbin0 -> 375 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/save.pngbin0 -> 1329 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/icons/save_as.pngbin0 -> 1024 bytes
-rwxr-xr-xsource/blender/freestyle/intern/app/interactiveshaderwindow4.ui103
-rwxr-xr-xsource/blender/freestyle/intern/app/optionswindow4.ui651
-rwxr-xr-xsource/blender/freestyle/intern/app/progressdialog4.ui26
-rwxr-xr-xsource/blender/freestyle/intern/app/src.pri50
-rwxr-xr-xsource/blender/freestyle/intern/app/stylewindow4.ui182
59 files changed, 8837 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/app/AppAboutWindow.cpp b/source/blender/freestyle/intern/app/AppAboutWindow.cpp
new file mode 100755
index 00000000000..d20e3f4e1ac
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppAboutWindow.cpp
@@ -0,0 +1,36 @@
+
+//
+// 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 <qmessagebox.h>
+#include "AppConfig.h"
+#include "AppAboutWindow.h"
+
+void AppAboutWindow::display() {
+ QMessageBox* mb;
+
+ mb = new QMessageBox("About " + Config::APPLICATION_NAME,
+ Config::ABOUT_STRING,
+ QMessageBox::NoIcon,
+ QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton, QMessageBox::NoButton,
+ NULL,
+ (Qt::WFlags)(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WA_DeleteOnClose));
+ mb->show();
+}
diff --git a/source/blender/freestyle/intern/app/AppAboutWindow.h b/source/blender/freestyle/intern/app/AppAboutWindow.h
new file mode 100755
index 00000000000..ee04d27ae71
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppAboutWindow.h
@@ -0,0 +1,40 @@
+//
+// Filename : AppAboutWindow.h
+// Author : Emmanuel Turquin
+// Purpose : Class to display a "About" window
+// Date of creation : 13/06/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 APPABOUTWINDOWS_H
+# define APPABOUTWINDOWS_H
+
+class AppAboutWindow
+{
+ public:
+
+ static void display();
+};
+
+#endif // APPABOUTWINDOWS_H
diff --git a/source/blender/freestyle/intern/app/AppCanvas.cpp b/source/blender/freestyle/intern/app/AppCanvas.cpp
new file mode 100755
index 00000000000..60d36880c12
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppCanvas.cpp
@@ -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 <QImage>
+
+#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 = (const char*)(Config::Path::getInstance()->getMapsDir().toAscii().data());
+}
+
+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/AppCanvas.h b/source/blender/freestyle/intern/app/AppCanvas.h
new file mode 100755
index 00000000000..703970c0fb1
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppCanvas.h
@@ -0,0 +1,84 @@
+#ifndef ARTCANVAS_H
+#define ARTCANVAS_H
+
+//------------------------------------------------------------------------------------------//
+//
+// FileName : AppCanvas.h
+// Author : Stephane Grabli
+// Purpose : Class to define the App Canvas.
+// Date Of Creation : 05/01/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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#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/AppConfig.cpp b/source/blender/freestyle/intern/app/AppConfig.cpp
new file mode 100755
index 00000000000..217f58ee806
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppConfig.cpp
@@ -0,0 +1,120 @@
+//
+// 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 "AppConfig.h"
+#include <iostream>
+using namespace std;
+namespace Config{
+ Path* Path::_pInstance = 0;
+ Path::Path(){
+ // get the home directory
+ _HomeDir = getEnvVar("HOME");
+ // get the root directory
+ setRootDir(getEnvVar("FREESTYLE_DIR"));
+ //setRootDir(QString("."));
+ _pInstance = this;
+ }
+ void Path::setRootDir(const QString& iRootDir){
+ _ProjectDir = iRootDir;
+ _ModelsPath = "";
+ _PatternsPath = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "data" +
+ QString(DIR_SEP.c_str()) +
+ "textures" +
+ QString(DIR_SEP.c_str()) +
+ "variation_patterns" +
+ QString(DIR_SEP.c_str());
+ _BrushesPath = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "data" +
+ QString(DIR_SEP.c_str()) +
+ "textures" +
+ QString(DIR_SEP.c_str()) +
+ "brushes" +
+ QString(DIR_SEP.c_str());
+ _PythonPath = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "python" +
+ QString(PATH_SEP.c_str()) +
+ _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "style_modules" +
+ QString(DIR_SEP.c_str()) ;
+ if (getenv("PYTHONPATH")) {
+ _PythonPath += QString(PATH_SEP.c_str()) + QString(getenv("PYTHONPATH"));
+ }
+#ifdef WIN32
+ _BrowserCmd = "C:\\Program Files\\Internet Explorer\\iexplore.exe %s";
+#else
+ _BrowserCmd = "mozilla %s";
+#endif
+ _HelpIndexPath = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "doc" +
+ QString(DIR_SEP.c_str()) +
+ "html" +
+ QString(DIR_SEP.c_str()) +
+ "index.html";
+ _PapersDir = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "data" +
+ QString(DIR_SEP.c_str()) +
+ "textures" +
+ QString(DIR_SEP.c_str()) +
+ "papers" +
+ QString(DIR_SEP.c_str());
+ _EnvMapDir = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "data" +
+ QString(DIR_SEP.c_str()) +
+ "env_map" +
+ QString(DIR_SEP.c_str());
+ _MapsDir = _ProjectDir +
+ QString(DIR_SEP.c_str()) +
+ "data" +
+ QString(DIR_SEP.c_str()) +
+ "maps" +
+ QString(DIR_SEP.c_str());
+ }
+ void Path::setHomeDir(const QString& iHomeDir){
+ _HomeDir = iHomeDir;
+ }
+ Path::~Path(){
+ _pInstance = 0;
+ }
+ Path* Path::getInstance() {
+ return _pInstance;
+ }
+ QString Path::getEnvVar(const QString& iEnvVarName){
+ QString value;
+ if (!getenv(iEnvVarName.toAscii().data())) {
+ cerr << "Warning: You may want to set the $"<< iEnvVarName.toAscii().data()
+ << " environment variable to use " << QString(Config::APPLICATION_NAME).toAscii().data() << "." << endl
+ << " Otherwise, the current directory will be used instead." << endl;
+ value = ".";
+ }else{
+ value = getenv(iEnvVarName.toAscii().data());
+ }
+ return value;
+ }
+
+} // End of namepace Config
+
diff --git a/source/blender/freestyle/intern/app/AppConfig.h b/source/blender/freestyle/intern/app/AppConfig.h
new file mode 100755
index 00000000000..54e00571275
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppConfig.h
@@ -0,0 +1,125 @@
+//
+// Filename : AppConfig.h
+// Author : Emmanuel Turquin
+// 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 APP_CONFIG_H
+# define APP_CONFIG_H
+
+# include <qstring.h>
+# include "../system/FreestyleConfig.h"
+# include "../system/Precision.h"
+
+using namespace std;
+
+namespace Config {
+
+ class Path{
+ protected:
+ static Path * _pInstance;
+ QString _ProjectDir;
+ QString _ModelsPath;
+ QString _PatternsPath;
+ QString _BrushesPath;
+ QString _PythonPath;
+ QString _BrowserCmd;
+ QString _HelpIndexPath;
+ QString _PapersDir;
+ QString _EnvMapDir;
+ QString _MapsDir;
+ QString _HomeDir;
+ public:
+ Path();
+ virtual ~Path();
+ static Path* getInstance();
+
+ void setRootDir(const QString& iRootDir) ;
+ void setHomeDir(const QString& iHomeDir) ;
+
+ const QString& getProjectDir() const {return _ProjectDir;}
+ const QString& getModelsPath() const {return _ModelsPath;}
+ const QString& getPatternsPath() const {return _PatternsPath;}
+ const QString& getBrushesPath() const {return _BrushesPath;}
+ const QString& getPythonPath() const {return _PythonPath;}
+ const QString& getBrowserCmd() const {return _BrowserCmd;}
+ const QString& getHelpIndexpath() const {return _HelpIndexPath;}
+ const QString& getPapersDir() const {return _PapersDir;}
+ const QString& getEnvMapDir() const {return _EnvMapDir;}
+ const QString& getMapsDir() const {return _MapsDir;}
+ const QString& getHomeDir() const {return _HomeDir;}
+
+ static QString getEnvVar(const QString& iEnvVarName);
+
+ };
+
+ //
+ // Configuration, default values
+ //
+ //////////////////////////////////////////////////////////////
+
+ // Application
+ static const QString APPLICATION_NAME(APPNAME);
+ static const QString APPLICATION_VERSION(APPVERSION);
+
+ // ViewMap
+ static const QString VIEWMAP_EXTENSION("vm");
+ static const QString VIEWMAP_MAGIC("ViewMap File");
+ static const QString VIEWMAP_VERSION("1.9");
+
+ // Style modules
+ static const QString STYLE_MODULE_EXTENSION("py");
+ static const QString STYLE_MODULES_LIST_EXTENSION("sml");
+
+ // Options
+ static const QString OPTIONS_DIR("." + APPLICATION_NAME);
+ static const QString OPTIONS_FILE("options.xml");
+ static const QString OPTIONS_CURRENT_DIRS_FILE("current_dirs.xml");
+ static const QString OPTIONS_QGLVIEWER_FILE("qglviewer.xml");
+
+ // Default options
+ static const real DEFAULT_SPHERE_RADIUS = 1.0;
+ static const real DEFAULT_DKR_EPSILON = 0.0;
+
+ // Papers
+ static const QString DEFAULT_PAPER_TEXTURE("whitepaper.jpg");
+
+ // Help & About texts
+ static const QString HELP_FILE("help.html");
+ static const QString ABOUT_STRING
+ (
+ "<CENTER><H2>" + APPLICATION_NAME + " " + APPLICATION_VERSION + "</H2>"
+ "<P>A programmable line drawing system</P></CENTER>"
+ "<UL>"
+ "<LI>Frédo Durand"
+ "<LI>Stéphane Grabli"
+ "<LI>François Sillion"
+ "<LI>Emmanuel Turquin"
+ "</UL>"
+ "<CENTER><B>(C) Artis 2003</B></CENTER>"
+ );
+
+} // End of namepace Config
+
+#endif // APP_CONFIG_H
diff --git a/source/blender/freestyle/intern/app/AppDensityCurvesWindow.cpp b/source/blender/freestyle/intern/app/AppDensityCurvesWindow.cpp
new file mode 100755
index 00000000000..fe2ae994f77
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppDensityCurvesWindow.cpp
@@ -0,0 +1,65 @@
+
+//
+// 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 "AppDensityCurvesWindow.h"
+#include "../scene_graph/NodeGroup.h"
+#include "AppGL2DCurvesViewer.h"
+#include <vector>
+using namespace std;
+
+
+AppDensityCurvesWindow::AppDensityCurvesWindow(QWidget *parent, const char *name, bool modal, Qt::WFlags fl)
+ : QDialog(parent, fl)
+{
+ setupUi(this);
+}
+AppDensityCurvesWindow::~AppDensityCurvesWindow(){
+}
+
+void AppDensityCurvesWindow::SetOrientationCurve(int i, const Vec2d& vmin, const Vec2d& vmax, const vector<Vec3r>& iCurve, const char *xlabel, const char *ylabel){
+ AppGL2DCurvesViewer * viewer = 0;
+ switch(i){
+ case 0:viewer = CurvesViewer0; break;
+ case 1:viewer = CurvesViewer1; break;
+ case 2:viewer = CurvesViewer2; break;
+ case 3:viewer = CurvesViewer3; break;
+ case 4:viewer = CurvesViewer4; break;
+ default:return;
+ }
+
+ viewer->SetCurve(vmin, vmax, iCurve, xlabel, ylabel);
+}
+
+void AppDensityCurvesWindow::SetLevelCurve(int i, const Vec2d& vmin, const Vec2d& vmax, const vector<Vec3r>& iCurve, const char *xlabel, const char *ylabel){
+ AppGL2DCurvesViewer * viewer = 0;
+ switch(i){
+ case 1:viewer = LevelCurveViewer1; break;
+ case 2:viewer = LevelCurveViewer2; break;
+ case 3:viewer = LevelCurveViewer3; break;
+ case 4:viewer = LevelCurveViewer4; break;
+ case 5:viewer = LevelCurveViewer5; break;
+ case 6:viewer = LevelCurveViewer6; break;
+ case 7:viewer = LevelCurveViewer7; break;
+ case 8:viewer = LevelCurveViewer8; break;
+ default:return;
+ }
+
+ viewer->SetCurve(vmin, vmax, iCurve, xlabel, ylabel);
+}
diff --git a/source/blender/freestyle/intern/app/AppDensityCurvesWindow.h b/source/blender/freestyle/intern/app/AppDensityCurvesWindow.h
new file mode 100755
index 00000000000..d7091440e06
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppDensityCurvesWindow.h
@@ -0,0 +1,85 @@
+//
+// Filename : AppDensityCurvesWindow.h
+// Author : Stephane Grabli
+// Purpose : Class to define the density curves display window
+// Date of creation : 14/03/04
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//
+// 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 APPDENSITYCURVESWINDOW_H
+# define APPDENSITYCURVESWINDOW_H
+
+#include "ui_dir/ui_densitycurveswindow4.h"
+#include <vector>
+#include "../geometry/Geom.h"
+using namespace std;
+using namespace Geometry;
+using namespace Ui;
+
+class NodeGroup;
+
+class AppDensityCurvesWindow : public QDialog, public DensityCurvesWindow
+{
+Q_OBJECT
+public:
+ AppDensityCurvesWindow(QWidget *parent = 0, const char *name = 0, bool modal = FALSE, Qt::WFlags fl = 0);
+ virtual ~AppDensityCurvesWindow();
+
+ /*! Sets the node that contains the orientation curve i in
+ * viewer i (among 5).
+ * \param i
+ * The number of the viewer where the curve must be displayed.(0<=i<5).
+ * \param vmin
+ * The x,y min of the curve
+ * \param vmax
+ * The x,y max of the curve
+ * \param iCurve
+ * The array of XYZ coordinates of the points.
+ * \param xlabel
+ * The label of the x-axis
+ * \param ylabel
+ * The label of the y-axis
+ */
+ void SetOrientationCurve(int i, const Vec2d& vmin, const Vec2d& vmax, const vector<Vec3r>& iCurve, const char *xlabel, const char *ylabel);
+
+ /*! Sets the node that contains the level curve i in
+ * viewer i (i in [1,8]).
+ * \param i
+ * The number of the viewer where the curve must be displayed.(0<=i<5).
+ * \param vmin
+ * The x,y min of the curve
+ * \param vmax
+ * The x,y max of the curve
+ * \param iCurve
+ * The array of XYZ coordinates of the points.
+ * \param xlabel
+ * The label of the x-axis
+ * \param ylabel
+ * The label of the y-axis
+ */
+ void SetLevelCurve(int i, const Vec2d& vmin, const Vec2d& vmax, const vector<Vec3r>& iCurve, const char *xlabel, const char *ylabel);
+};
+
+#endif // APPDENSITYCURVESWINDOW_H
+
+
diff --git a/source/blender/freestyle/intern/app/AppGL2DCurvesViewer.cpp b/source/blender/freestyle/intern/app/AppGL2DCurvesViewer.cpp
new file mode 100755
index 00000000000..0915a4c3cbd
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppGL2DCurvesViewer.cpp
@@ -0,0 +1,152 @@
+
+//
+// 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 "AppGL2DCurvesViewer.h"
+#include "../rendering/GLRenderer.h"
+#include "../scene_graph/NodeShape.h"
+#include "../scene_graph/LineRep.h"
+#include "../scene_graph/VertexRep.h"
+
+AppGL2DCurvesViewer::AppGL2DCurvesViewer(QWidget *iParent, const char *iName)
+: QGLViewer(iParent)
+{
+ _RootNode.SetLightingEnabled(false);
+ _RootNode.SetLineWidth(1.0);
+ _pGLRenderer = new GLRenderer;
+}
+AppGL2DCurvesViewer::~AppGL2DCurvesViewer(){
+ makeCurrent();
+ _RootNode.destroy();
+ if(_pGLRenderer)
+ delete _pGLRenderer;
+}
+
+void AppGL2DCurvesViewer::SetRange(const Vec2d& vmin, const Vec2d& vmax, const char * xlabel, const char *ylabel){
+ _vmin = vmin;
+ _vmax = vmax;
+ _xmargin = (vmax.x()-vmin.x())/20.0;
+ _ymargin = (vmax.y()-vmin.y())/20.0;
+ _left = vmin.x()-_xmargin;
+ _right = vmax.x()+_xmargin;
+ _bottom = vmin.y()- _ymargin;
+ _top = vmax.y()+_ymargin;
+ if(xlabel)
+ _xlabel = xlabel;
+ if(ylabel)
+ _ylabel = ylabel;
+}
+void AppGL2DCurvesViewer::SetCurve(const Vec2d& vmin, const Vec2d& vmax, const vector<Vec3r>& iPoints, const char *xlabel, const char *ylabel){
+ SetRange(vmin, vmax, xlabel, ylabel);
+ vector<Node*> nodes;
+ _RootNode.RetrieveChildren(nodes);
+ _RootNode.DetachChildren();
+ for(vector<Node*>::iterator n=nodes.begin(), nend=nodes.end();
+ n!=nend;
+ ++n){
+ delete (*n);
+ }
+ _curve.clear();
+ _curve = iPoints;
+ NodeGroup * curveNode = new NodeGroup;
+ NodeShape * shape = new NodeShape;
+ shape->material().SetDiffuse(0,0,0,1);
+ curveNode->AddChild(shape);
+ shape->AddRep(new LineRep(iPoints));
+ for(vector<Vec3r>::const_iterator v=iPoints.begin(), vend=iPoints.end();
+ v!=vend;
+ ++v){
+ shape->AddRep(new VertexRep(v->x(), v->y(), v->z()));
+ }
+ _RootNode.AddChild(curveNode);
+ updateGL();
+}
+
+void AppGL2DCurvesViewer::AddNode(Node* iNode){
+ _RootNode.AddChild(iNode);
+}
+
+void AppGL2DCurvesViewer::DetachNode(Node* iNode){
+ _RootNode.DetachChild(iNode);
+}
+
+void AppGL2DCurvesViewer::RetrieveNodes(vector<Node*>& oNodes){
+ _RootNode.RetrieveChildren(oNodes);
+}
+
+void AppGL2DCurvesViewer::init(){
+ glClearColor(1,1,1,1);
+ _left = 0;
+ _right = width();
+ _bottom = 0;
+ _top = height();
+}
+void AppGL2DCurvesViewer::draw(){
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+// // Projection Matrix
+// //==================
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(_left,_right, _bottom, _top, -1.0, 1.0);
+
+ //Modelview Matrix
+ //================
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glDisable(GL_DEPTH_TEST);
+ // draw axis
+ glColor3f(0.5, 0.5, 0.5);
+ // x axis
+ glBegin(GL_LINES);
+ glVertex2f(_left, _vmin.y());
+ glVertex2f(_vmax.x(), _vmin.y());
+ glEnd();
+ QFont serifFont( "Times", 8);
+ if(!_xlabel.isEmpty()){
+ renderText(width()-30, height()-1, _xlabel, serifFont);
+ //renderText(_vmax.x()-_xmargin, _vmin.y(), 0, _xlabel, serifFont);
+ }
+
+ // y axis
+ glBegin(GL_LINES);
+ glVertex2f(_vmin.x(), _bottom);
+ glVertex2f(_vmin.x(), _vmax.y());
+ glEnd();
+ if(!_ylabel.isEmpty()){
+ //renderText(_vmin.x(), _vmax.y()-3*_ymargin, _ylabel, serifFont);
+ renderText(12, 10, _ylabel, serifFont);
+ }
+ _RootNode.accept(*_pGLRenderer);
+ serifFont.setPointSize(7);
+ for(vector<Vec3r>::iterator v=_curve.begin(), vend=_curve.end();
+ v!=vend;
+ ++v){
+ if(v->y() == 0)
+ continue;
+ QString label = QString( "(%1, %2)" )
+ .arg( (int)v->x())
+ .arg( v->y(), 0, 'E', 1 );
+
+ renderText(v->x(), v->y(), 0, label, serifFont);
+ }
+ glPopAttrib();
+
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/app/AppGL2DCurvesViewer.h b/source/blender/freestyle/intern/app/AppGL2DCurvesViewer.h
new file mode 100755
index 00000000000..c0bb8b4109c
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppGL2DCurvesViewer.h
@@ -0,0 +1,80 @@
+//
+// Filename : AppGL2DCurvesViewer.h
+// Author : Stephane Grabli
+// Purpose : 2D GL Curves viewer
+// Date of creation : 14/03/2004
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//
+// 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 APPGL2DCURVESVIEWER_H
+# define APPGL2DCURVESVIEWER_H
+
+# include <QGLViewer/qglviewer.h>
+# include "../scene_graph/NodeDrawingStyle.h"
+# include <qstring.h>
+
+class GLRenderer;
+
+class AppGL2DCurvesViewer : public QGLViewer
+{
+ Q_OBJECT
+
+public:
+
+ AppGL2DCurvesViewer(QWidget *iParent, const char *iName = 0);
+ virtual ~AppGL2DCurvesViewer();
+
+ /*! Sets the ranges.
+ */
+ void SetRange(const Vec2d& vmin, const Vec2d& vmax, const char * xlabel, const char *ylabel);
+ void SetCurve(const Vec2d& vmin, const Vec2d& vmax, const vector<Vec3r>& iPoints, const char *xlabel, const char *ylabel);
+ void AddNode(Node* iNode);
+ void DetachNode(Node* iNode);
+ void RetrieveNodes(vector<Node*>& oNodes);
+
+ virtual QSize sizeHint() const {return QSize(200,200);}
+ virtual QSizePolicy sizePolicy() const {return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);}
+protected:
+ virtual void init();
+ virtual void draw();
+
+private:
+ NodeDrawingStyle _RootNode;
+ GLRenderer *_pGLRenderer;
+ vector<Vec3r> _curve;
+ Vec2d _vmin; // curve bbox min
+ Vec2d _vmax; // curve bbox max
+ double _left; // frustum clipping planes (slightly differemt from the bbox for a clear view)
+ double _right;
+ double _bottom;
+ float _xmargin; // margin around plot in x direction
+ float _ymargin; // margin around plot in y direction
+ double _top;
+ QString _xlabel;
+ QString _ylabel;
+
+};
+
+
+#endif // APPGL2DCURVESVIEWER_H
+
diff --git a/source/blender/freestyle/intern/app/AppGLWidget.cpp b/source/blender/freestyle/intern/app/AppGLWidget.cpp
new file mode 100755
index 00000000000..d59ad716c18
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppGLWidget.cpp
@@ -0,0 +1,1049 @@
+
+//
+// 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 <qtextstream.h>
+#include <qimage.h>
+#include <qtabwidget.h>
+#include <qtextedit.h>
+#include <QMouseEvent>
+#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"
+
+// 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(QWidget *iParent, const char *iName)
+ : QGLViewer(iParent)
+{
+ _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 QString sep(Config::DIR_SEP.c_str());
+ const QString 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() ;
+ _enableUpdateSilhouettes = false;
+ connect(fr, SIGNAL(modified()), this, SLOT(updateSilhouettes()));
+ _captureMovie = false;
+ // _frontBufferFlag = false;
+ // _backBufferFlag = true;
+ _record = false;
+}
+
+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::SetMainWindow(QMainWindow *iMainWindow) {
+ _pMainWindow = iMainWindow;
+}
+void AppGLWidget::captureMovie()
+{
+ _captureMovie = true;
+ setSnapshotFormat("BMP");
+ setSnapshotFileName("anim");
+ camera()->playPath(0);
+ //_captureMovie = false;
+}
+
+void
+AppGLWidget::updateSilhouettes()
+{
+ if(!_enableUpdateSilhouettes || !g_pController)
+ return;
+ g_pController->ComputeViewMap();
+ g_pController->DrawStrokes();
+ if(_captureMovie)
+ {
+ if(!camera()->keyFrameInterpolator(0)->interpolationIsStarted())
+ {
+ _captureMovie = false;
+ return;
+ }
+ saveSnapshot(true);
+ }
+}
+
+void
+AppGLWidget::select(const QMouseEvent *e) {
+
+ // 3D Shape selection
+
+ if (_selection_mode) {
+
+ // Make openGL context current
+ makeCurrent();
+
+ const unsigned SENSITIVITY = 4;
+ const unsigned NB_HITS_MAX = 64;
+
+ // Prepare the selection mode
+ static GLuint hits[NB_HITS_MAX];
+
+ glSelectBuffer(NB_HITS_MAX, hits);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+
+ // Loads the matrices
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ GLint viewport[4];
+ camera()->getViewport(viewport);
+ gluPickMatrix(static_cast<GLdouble>(e->x()), static_cast<GLdouble>(e->y()), SENSITIVITY, SENSITIVITY, viewport);
+
+ // loadProjectionMatrix() first resets the GL_PROJECTION matrix with a glLoadIdentity.
+ // Give false as a parameter in order to prevent this and to combine the matrices.
+ camera()->loadProjectionMatrix(false);
+
+ camera()->loadModelViewMatrix();
+
+ // Render scene with objects ids
+ _pSelectRenderer->setSelectRendering(true);
+ DrawScene(_pSelectRenderer);
+ glFlush();
+
+ // Get the results
+ GLint nb_hits = glRenderMode(GL_RENDER);
+
+ if (nb_hits <= 0) {
+ _pSelectRenderer->setSelectedId(-1);
+ return;
+ }
+
+ // Interpret results
+ unsigned int zMin = hits[1];
+ unsigned int selected = hits[3];
+ for (int i=1; i<nb_hits; ++i)
+ if (hits[i*4+1] < zMin)
+ {
+ zMin = hits[i*4+1];
+ selected = hits[i*4+3];
+ }
+ _pSelectRenderer->setSelectedId(selected);
+
+ cout << "SHAPE" << endl;
+ cout << "-----" << endl;
+ cout << "Id: " << _pSelectRenderer->getSelectedId() << endl;
+ cout << endl;
+
+ return;
+ }
+
+ // ViewMap selection
+
+ FEdge *fe = g_pController->SelectFEdge(e->x(), height()-e->y());
+ if (!fe)
+ return;
+ ViewEdge * ve = fe->viewedge();
+
+ if (ve) {
+ cout << "VIEWEDGE" << endl;
+ cout << "--------" << endl;
+ cout << "ViewEdge Id: " << ve->getId().getFirst() << ", " << ve->getId().getSecond() << endl;
+ cout << "Shape Id: " << ve->shape_id() << endl;
+ cout << "Nature: " << ve->getNature() << endl;
+ cout << "QI: " << ve->qi() << endl;
+ if(ve->aShape())
+ cout << "Occludee: " << ve->aShape()->getId() << endl;
+ else
+ cout << "Occludee: NULL" << endl ;
+ cout << endl;
+
+ cout << "FEDGE" << endl;
+ cout << "-----" << endl;
+ cout << "FEdge Id: " << fe->getId().getFirst() << ", " << fe->getId().getSecond() << endl;
+ cout << "Vertex A Id: " << fe->vertexA()->getId() << endl;
+ cout << "Vertex B Id: " << fe->vertexB()->getId() << endl;
+ cout << endl;
+
+ vector<ViewEdge*> vedges;
+ vedges.push_back(ve);
+ _p2DSelectionNode->AddChild(g_pController->BuildRep(vedges.begin(), vedges.end()));
+ // FEdge
+ LineRep * fedgeRep = new LineRep(fe->vertexA()->point2d(), fe->vertexB()->point2d());
+ fedgeRep->SetWidth(3.f);
+ NodeShape * fedgeNode = new NodeShape;
+ fedgeNode->AddRep(fedgeRep);
+ fedgeNode->material().SetDiffuse(0.2, 1, 0.2, 1.0);
+ _p2DSelectionNode->AddChild(fedgeNode);
+ //SVertex A
+ Vec3r A(fe->vertexA()->point2d());
+ VertexRep * aVertexRep = new VertexRep(A.x(), A.y(), A.z());
+ aVertexRep->SetPointSize(3.f);
+ NodeShape * aVertexNode = new NodeShape;
+ aVertexNode->AddRep(aVertexRep);
+ aVertexNode->material().SetDiffuse(1, 0, 0, 1.0);
+ _p2DSelectionNode->AddChild(aVertexNode);
+ // and its fedges
+ const vector<FEdge*>& afedges = fe->vertexA()->fedges();
+ vector<FEdge*>::const_iterator f=afedges.begin(), fend=afedges.end();
+ for(;
+ f!=fend;
+ ++f)
+ {
+ LineRep * lrep = new LineRep((*f)->vertexA()->point2d(), (*f)->vertexB()->point2d());
+ lrep->SetWidth(1.f);
+ aVertexNode->AddRep(lrep);
+ }
+ //SVertex B
+ Vec3r B(fe->vertexB()->point2d());
+ VertexRep * bVertexRep = new VertexRep(B.x(), B.y(), B.z());
+ bVertexRep->SetPointSize(3.f);
+ NodeShape * bVertexNode = new NodeShape;
+ bVertexNode->AddRep(bVertexRep);
+ bVertexNode->material().SetDiffuse(0, 0, 1, 1.0);
+ _p2DSelectionNode->AddChild(bVertexNode);
+ // and its fedges
+ const vector<FEdge*>& bfedges = fe->vertexB()->fedges();
+ f=bfedges.begin();
+ fend=bfedges.end();
+ for(;
+ f!=fend;
+ ++f)
+ {
+ LineRep * lrep = new LineRep((*f)->vertexA()->point2d(), (*f)->vertexB()->point2d());
+ lrep->SetWidth(1.f);
+ bVertexNode->AddRep(lrep);
+ }
+
+ }
+}
+
+
+void
+AppGLWidget::mousePressEvent(QMouseEvent *e)
+{
+ _p2DSelectionNode->destroy();
+ if (e->button() == Qt::LeftButton)
+ {
+ if(e->modifiers() == Qt::ShiftModifier)
+ {
+ select(e);
+ }
+ else if(e->modifiers() == Qt::ControlModifier)
+ {
+ // Density Observation
+ g_pController->displayDensityCurves(e->x(), height()-1-e->y());
+ }else{
+ QGLViewer::mousePressEvent(e);
+ }
+ updateGL();
+ }
+ else
+ QGLViewer::mousePressEvent(e);
+}
+
+void
+AppGLWidget::mouseReleaseEvent ( QMouseEvent * e )
+{
+ // if(g_pController)
+ // g_pController->ComputeViewMap();
+ // g_pController->DrawStrokes();
+ QGLViewer::mouseReleaseEvent(e);
+}
+
+void
+AppGLWidget::keyPressEvent(QKeyEvent* e)
+{
+ switch (e->key()) {
+
+ case Qt::Key_U:
+ _enableUpdateSilhouettes = !_enableUpdateSilhouettes;
+ break;
+ case Qt::Key_Escape:
+ break;
+ case Qt::Key_V:
+ g_pController->toggleVisibilityAlgo();
+ break;
+ case Qt::Key_R:
+ if(e->modifiers() == Qt::ShiftModifier){
+ _record = !_record;
+ if(_record){
+ setSnapshotFormat("JPEG");
+ setSnapshotFileName("anim");
+ g_pController->displayMessage("record", true);
+ }else{
+ g_pController->displayMessage("");
+ }
+
+ }
+ else if(_cameraStateSaved) {
+ setCameraState(_cameraPosition, _cameraOrientation);
+ updateGL();
+ }
+ break;
+ case Qt::Key_M:
+ _drawEnvMap = !_drawEnvMap ;
+ updateGL(); break;
+ case Qt::Key_Plus:
+ Canvas::getInstance()->changePaperTexture(true);updateGL();
+ break;
+ case Qt::Key_Minus:
+ Canvas::getInstance()->changePaperTexture(false);updateGL();
+ break;
+ case Qt::Key_P:
+ Canvas::getInstance()->togglePaperTexture();updateGL();
+ break;
+ case Qt::Key_PageUp:
+ if(e->modifiers() == Qt::ControlModifier)
+ _blendFunc = (_blendFunc + 1) % 2;
+ else {
+ _currentEnvMap++;
+ if(_currentEnvMap > _maxId)
+ _currentEnvMap = 1;
+ }
+ updateGL();
+ break;
+ case Qt::Key_PageDown:
+ if(e->modifiers() == Qt::ControlModifier)
+ _blendFunc = (_blendFunc + 1) % 2;
+ else {
+ _currentEnvMap--;
+ if(_currentEnvMap < 1)
+ _currentEnvMap = _maxId;
+ }
+ updateGL();
+ break;
+ case Qt::Key_1: _ModelRootNode->SetStyle(DrawingStyle::FILLED); updateGL(); break;
+ case Qt::Key_2: _ModelRootNode->SetStyle(DrawingStyle::LINES); _ModelRootNode->SetLineWidth(1.0); updateGL(); break;
+ case Qt::Key_3: _ModelRootNode->SetStyle(DrawingStyle::INVISIBLE); updateGL(); break;
+ case Qt::Key_B:
+ {
+// if(e->state() == ShiftButton)
+// {
+// g_pController->toggleEdgeTesselationNature(Nature::BORDER); updateGL(); break;
+// }
+// else
+ {
+ _drawBBox == true ? _drawBBox = false : _drawBBox = true; updateGL(); break;
+ }
+ }
+// case Key_C:
+// if(e->state() == ShiftButton)
+// {
+// g_pController->toggleEdgeTesselationNature(Nature::CREASE); updateGL(); break;
+// }
+// break;
+ case Qt::Key_S:
+ {
+// if(e->state() == ShiftButton)
+// {
+// g_pController->toggleEdgeTesselationNature(Nature::SILHOUETTE); updateGL(); break;
+// }
+// else
+ {
+ _silhouette == true ? _silhouette = false : _silhouette = true; updateGL(); break;
+ }
+ }
+ case Qt::Key_L:
+ {
+ _selection_mode = !_selection_mode; updateGL(); break;
+ }
+ break;
+ case Qt::Key_E:
+ {
+ _fedges == true ? _fedges = false : _fedges = true; updateGL(); break;
+ }
+ break;
+ case Qt::Key_D:
+ {
+ _debug == true ? _debug = false : _debug = true; updateGL();
+ }
+ break;
+ case Qt::Key_F2: _Draw2DScene == true ? _Draw2DScene = false : _Draw2DScene = true; updateGL(); break;
+ case Qt::Key_F3: _Draw3DScene == true ? _Draw3DScene = false : _Draw3DScene = true; updateGL(); break;
+ default:
+ QGLViewer::keyPressEvent(e);
+ }
+}
+
+void AppGLWidget::LoadEnvMap(const char *filename)
+{
+ GLuint textureId;
+ GLubyte *data;
+ //sgiImage img;
+ //cout << filename << endl;
+ QImage img(filename, "PNG");
+ QImage glImage = QGLWidget::convertToGLFormat(img);
+ int d = glImage.depth();
+ //data = img.read(filename); // tres beau bleu gris mauve!!
+ // allocate a texture name
+ glGenTextures( 1, &textureId );
+ if(textureId > _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, glImage.width(), glImage.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits() );
+}
+
+void AppGLWidget::help(){
+ emit helpRequired();
+
+ bool resize = false;
+ int width=600;
+ int height=400;
+
+ static QString label[] = {" &Keyboard ", " &Mouse "};
+
+ QTabWidget * hWidget = helpWidget();
+ if (!hWidget){
+ hWidget = new QTabWidget(NULL);
+ hWidget->setWindowTitle("Control Bindings");
+ resize = true;
+ for (int i=0; i<2; ++i){
+ QTextEdit* tab = new QTextEdit(hWidget);
+ //tab->setAcceptRichText(true); // FIXME: commented because qt 4.0 is incomplete
+#if QT_VERSION >= 300
+ tab->setReadOnly(true);
+#endif
+ hWidget->insertTab(i, tab, label[i]);
+ }
+ }
+
+#if QT_VERSION < 300
+ const int currentPageIndex = hWidget->currentPageIndex();
+#endif
+
+ for (int i=0; i<2; ++i)
+ {
+ QString text;
+ switch (i)
+ {
+ case 0 : text = keyboardString(); break;
+ case 1 : text = mouseString(); break;
+ default : break;
+ }
+
+#if QT_VERSION < 300
+ hWidget->setCurrentPage(i);
+ QTextEdit* textEdit = (QTextEdit*)(hWidget->currentPage());
+#else
+ hWidget->setCurrentIndex(i);
+ QTextEdit* textEdit = (QTextEdit*)(hWidget->currentWidget());
+#endif
+ textEdit->setHtml(text);
+
+ if (resize && (textEdit->heightForWidth(width) > height))
+ height = textEdit->heightForWidth(width);
+ }
+
+#if QT_VERSION < 300
+ hWidget->setCurrentPage(currentPageIndex);
+#endif
+
+ if (resize)
+ hWidget->resize(width, height+40); // 40 is tabs' height
+ hWidget->show();
+ hWidget->raise();
+}
+
+QString AppGLWidget::helpString() const{
+ QString pdir(Config::Path::getInstance()->getProjectDir());
+ QString text = "<a href=\"" + pdir + "/doc/html/index.html\">help content</a>";
+ return text;
+}
+
+QString AppGLWidget::mouseString() const{
+ QString text("<table border=\"1\" cellspacing=\"0\">\n");
+ text += "<tr bgcolor=\"#eebf00\"><th align=\"center\">Button</th><th align=\"center\">Description</th></tr>\n";
+ text += "<tr><td><b>Shift+Left</b></td><td>If view map exists, selects a view edge.<br> If in selection mode, selects a shape</td></tr>";
+ text += "</table>";
+ text += QGLViewer::mouseString();
+ return text;
+}
+
+QString AppGLWidget::keyboardString() const {
+
+ QString text("<table border=\"1\" cellspacing=\"0\">\n");
+ text += "<tr bgcolor=\"#eebf00\"><th align=\"center\">Key</th><th align=\"center\">Description</th></tr>\n";
+ text += "<tr><td><b>F2</b></td><td>Toggles 2D Scene display</td></tr>";
+ text += "<tr><td><b>F3</b></td><td>Toggles 3D Scene display</td></tr>";
+
+ text += "<tr><td><b>1</b></td><td>Filled display mode</td></tr>";
+ text += "<tr><td><b>2</b></td><td>Lines display mode</td></tr>";
+ text += "<tr><td><b>3</b></td><td>Invisible display mode</td></tr>";
+
+ text += "<tr><td><b>E</b></td><td>Toggles ViewMap display</td></tr>";
+ text += "<tr><td><b>B</b></td><td>Toggles bounding boxes display</td></tr>";
+ text += "<tr><td><b>S</b></td><td>Toggles GL silhouettes display</td></tr>";
+ text += "<tr><td><b>D</b></td><td>Toggles debug information display</td></tr>";
+ text += "<tr><td><b>L</b></td><td>Toggles shape selection mode</td></tr>";
+ text += "<tr><td><b>P</b></td><td>Toggles paper texture display</td></tr>";
+ text += "<tr><td><b>M</b></td><td>Toggles toon shading</td></tr>";
+ text += "<tr><td><b>V</b></td><td>Toggles visibility algorithm</td></tr>";
+
+ text += "<tr><td><b>R</b></td><td>Reset camera to the latest ViewMap computation settings</td></tr>";
+ text += "<tr><td><b>Shift+R</b></td><td>Toggles snapshots mode</td></tr>";
+
+ text += "<tr><td><b>U</b></td><td>Recomputes the ViewMap when the view changes</td></tr>";
+
+ text += "<tr><td><b>+/-</b></td><td>Change paper texture</td></tr>";
+ text += "<tr><td><b>PgUp/PgDn</b></td><td>Changes EnvMap</td></tr>";
+ text += "<tr><td><b>Ctrl+PgUp/PgDn</b></td><td>Changes blending function</td></tr>";
+ text += "</table>";
+ text += QGLViewer::keyboardString();
+ return text;
+}
+
+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();
+ QString envmapDir = cpath->getEnvMapDir();
+ LoadEnvMap((envmapDir + QString("gray00.png")).toAscii().data());
+ //LoadEnvMap(Config::ENV_MAP_DIR + "gray01.bmp");
+ LoadEnvMap((envmapDir + QString("gray02.png")).toAscii().data());
+ LoadEnvMap((envmapDir + QString("gray03.png")).toAscii().data());
+ LoadEnvMap((envmapDir + QString("brown00.png")).toAscii().data());
+ 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);
+ }
+ if(_captureMovie)
+ {
+ if(!camera()->keyFrameInterpolator(0)->interpolationIsStarted())
+ {
+ _captureMovie = false;
+ return;
+ }
+ 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/AppGLWidget.h b/source/blender/freestyle/intern/app/AppGLWidget.h
new file mode 100755
index 00000000000..24bb2c7229b
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppGLWidget.h
@@ -0,0 +1,526 @@
+//
+// 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 AppGLWidget : public QGLViewer
+{
+ Q_OBJECT
+
+public:
+
+ AppGLWidget(QWidget *iParent, const char *iName = 0);
+ ~AppGLWidget();
+
+public slots:
+ virtual void updateSilhouettes();
+
+public:
+ virtual void help();
+
+ // 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()
+ {
+ qglviewer::Vec min_(_ModelRootNode->bbox().getMin()[0],
+ _ModelRootNode->bbox().getMin()[1],
+ _ModelRootNode->bbox().getMin()[2]);
+ qglviewer::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 __max((float)_maxAbs/5,(float)(-_maxAbs+camera()->distanceToSceneCenter()));
+ return camera()->zNear();
+ }
+
+ inline real zfar() const {
+ // return _maxAbs+camera()->distanceToSceneCenter();
+ 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(qglviewer::Vec(position[0], position[1], position[2]));
+ camera()->setOrientation(qglviewer::Quaternion(orientation[0], orientation[1], orientation[2], orientation[3]));
+ }
+
+ void getCameraState(float* position, float* orientation) const {
+ qglviewer::Vec pos = camera()->position();
+ qglviewer::Quaternion 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();
+
+ // help
+ virtual QString helpString() const ;
+
+ virtual QString mouseString() const;
+ virtual QString keyboardString() const;
+
+protected:
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent ( QMouseEvent * e ) ;
+ virtual void select(const QMouseEvent *);
+ virtual void keyPressEvent(QKeyEvent* e);
+ 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;
+};
+
+#endif // ARTGLWIDGET_H
diff --git a/source/blender/freestyle/intern/app/AppInteractiveShaderWindow.cpp b/source/blender/freestyle/intern/app/AppInteractiveShaderWindow.cpp
new file mode 100755
index 00000000000..b074c85f9f9
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppInteractiveShaderWindow.cpp
@@ -0,0 +1,119 @@
+
+//
+// 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 <QTextEdit>
+#include <QFileDialog>
+#include "AppConfig.h"
+#include "Controller.h"
+#include "AppInteractiveShaderWindow.h"
+#include "QStyleModuleSyntaxHighlighter.h"
+
+AppInteractiveShaderWindow::AppInteractiveShaderWindow(QWidget* parent /* = 0 */, const char* name /* = 0 */, bool modal /* = FALSE */, Qt::WFlags fl /* = 0 */)
+: InteractiveShaderWindow() // parent, name, modal, fl)
+{
+ setupUi(this);
+ _CurrentShaderRow = -1;
+ _syntaxHighlighter = new QStyleModuleSyntaxHighlighter(TextArea);
+ // signals and slots connections
+ connect( CancelButton, SIGNAL( clicked() ), this, SLOT( fileClose() ) );
+ connect( SaveButton, SIGNAL( clicked() ), this, SLOT( fileSave() ) );
+ connect( SaveAsButton, SIGNAL( clicked() ), this, SLOT( fileSaveAs() ) );
+ connect( OkButton, SIGNAL( clicked() ), this, SLOT( fileOk() ) );
+}
+
+AppInteractiveShaderWindow::~AppInteractiveShaderWindow()
+{
+ if(_syntaxHighlighter){
+ delete _syntaxHighlighter;
+ }
+}
+
+void AppInteractiveShaderWindow::fileOk()
+{
+ fileSave();
+ fileClose();
+}
+
+void AppInteractiveShaderWindow::fileClose()
+{
+ TextArea->clear();
+ close();
+}
+
+void AppInteractiveShaderWindow::fileSave()
+{
+ QFile file(_CurrentShader);
+ if ( !file.open( QIODevice::WriteOnly ) )
+ return;
+ QTextStream ts( &file );
+ ts << TextArea->toPlainText();
+
+ file.close();
+ emit save();
+ g_pController->setModified(_CurrentShaderRow, true);
+}
+
+void AppInteractiveShaderWindow::fileSaveAs()
+{
+ QFileInfo fi1(_CurrentShader);
+ QString ext1 = fi1.suffix();
+ QString fn;
+
+ if (ext1 == Config::STYLE_MODULE_EXTENSION)
+ fn = QFileDialog::getSaveFileName(this,
+ "save file dialog"
+ "Choose a file",
+ g_pController->getModulesDir(),
+ "Style modules (*." + Config::STYLE_MODULE_EXTENSION + ")");
+ if (!fn.isEmpty() && (_CurrentShader == fn))
+ fileSave();
+ else if (!fn.isEmpty())
+ {
+ QFileInfo fi2(fn);
+ QString ext2 = fi2.suffix();
+ if (ext1 != ext2)
+ fn += "." + ext1;
+ QFile file(fn);
+ if ( !file.open( QIODevice::WriteOnly ) )
+ return;
+ QTextStream ts( &file );
+ ts << TextArea->toPlainText();
+ file.close();
+ g_pController->AddStyleModule(fn.toAscii().data());
+ g_pController->setModulesDir(fi2.dir().path());
+ }
+}
+
+void AppInteractiveShaderWindow::DisplayShader(QString& iName)
+{
+ _CurrentShader = iName;
+ QFile file( iName);
+ if ( !file.open( QIODevice::ReadOnly ) )
+ return;
+
+ QTextStream ts( &file );
+ TextArea->setText( ts.readAll() );
+ TextArea->viewport()->setFocus();
+
+ // Set window title:
+ QFileInfo fi(iName);
+ setWindowTitle(fi.fileName());
+ g_pController->setModulesDir(fi.dir().path());
+}
diff --git a/source/blender/freestyle/intern/app/AppInteractiveShaderWindow.h b/source/blender/freestyle/intern/app/AppInteractiveShaderWindow.h
new file mode 100755
index 00000000000..58f2aa1f01a
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppInteractiveShaderWindow.h
@@ -0,0 +1,73 @@
+#ifndef ARTINTERACTIVESHADERWINDOW_H
+#define ARTINTERACTIVESHADERWINDOW_H
+
+//------------------------------------------------------------------------------------------//
+//
+// FileName : AppInteractiveShaderWindow.h
+// Author : Stephane Grabli
+// Purpose : Class to define the graphic window displaying the interactive shader
+// Date Of Creation : 21/10/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.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include "ui_dir/ui_interactiveshaderwindow4.h"
+#include <QKeyEvent>
+
+using namespace Ui;
+
+class QStyleModuleSyntaxHighlighter;
+class AppInteractiveShaderWindow : public QDialog, public InteractiveShaderWindow
+{
+ Q_OBJECT
+ public:
+ AppInteractiveShaderWindow(QWidget *parent = 0, const char *name = 0, bool modal = FALSE, Qt::WFlags fl = 0);
+ virtual ~AppInteractiveShaderWindow();
+
+public slots:
+ virtual void fileOk();
+ virtual void fileClose();
+ virtual void fileSave();
+ virtual void fileSaveAs();
+
+ void DisplayShader(QString& iName);
+ void setCurrentShaderRow(int current) { _CurrentShaderRow = current; }
+ int getCurrentShaderRow() const { return _CurrentShaderRow; }
+
+ signals:
+ void save( );
+
+ protected:
+
+ void keyPressEvent(QKeyEvent *e) {
+ if (e->key() == Qt::Key_Escape)
+ return;
+ QDialog::keyPressEvent(e);
+ }
+
+ private:
+ int _CurrentShaderRow;
+ QString _CurrentShader;
+ QStyleModuleSyntaxHighlighter *_syntaxHighlighter;
+};
+
+#endif
+
diff --git a/source/blender/freestyle/intern/app/AppMainWindow.cpp b/source/blender/freestyle/intern/app/AppMainWindow.cpp
new file mode 100755
index 00000000000..03b4f3a28ea
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppMainWindow.cpp
@@ -0,0 +1,288 @@
+//
+// 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 <QApplication>
+#include <QCursor>
+#include <QProgressDialog>
+#include <QFileDialog>
+#include <QFile>
+#include <QStatusBar>
+#include <QToolBar>
+#include <QToolButton>
+#include <QLayout>
+#include "AppMainWindow.h"
+#include "AppGLWidget.h"
+#include "Controller.h"
+#include "AppConfig.h"
+
+AppMainWindow::AppMainWindow(QWidget *parent, const char *name, Qt::WindowFlags f)
+ : QMainWindow(parent, f) // parent, name, f)
+{
+ setupUi(this);
+ pQGLWidget = new AppGLWidget(this);
+ gridLayout->addWidget(pQGLWidget);
+
+ // setCaption(Config::APPLICATION_NAME + " " + Config::APPLICATION_VERSION);
+ setGeometry(20,20,700,700);
+ pQGLWidget->SetMainWindow(this);
+
+ _ProgressBar = new QProgressDialog(Config::APPLICATION_NAME + " Progress Dialog", "Cancel",
+ 0, 100, this);
+ // signals and slots connections
+ connect( actionOpen, SIGNAL( triggered() ), this, SLOT( fileOpen() ) );
+ connect( actionQuit, SIGNAL( triggered() ), this, SLOT( close() ) );
+ connect( actionClose, SIGNAL( triggered() ), this, SLOT( fileClose() ) );
+ connect( actionComputeViewMap, SIGNAL( triggered() ), this, SLOT( ComputeViewMap() ) );
+ connect( actionSave, SIGNAL( triggered() ), this, SLOT( ViewMapFileSave() ) );
+ connect( actionStyleModelerWindow, SIGNAL( triggered() ), this, SLOT( DisplayStylesWindow() ) );
+ connect( actionOptionsWindow, SIGNAL( triggered() ), this, SLOT( DisplayOptionsWindow() ) );
+ connect( actionComputeStrokes, SIGNAL( triggered() ), this, SLOT( ComputeStrokes() ) );
+ connect( actionHelp, SIGNAL( triggered() ), this, SLOT( DisplayHelp() ) );
+ connect( actionSaveSnapshot, SIGNAL( triggered() ), this, SLOT( Snapshot() ) );
+ connect( actionCaptureMovie, SIGNAL( triggered() ), this, SLOT( captureMovie() ) );
+ connect( actionResetInterpreter, SIGNAL( triggered() ), this, SLOT( ResetInterpreter() ) );
+ connect( actionSaveDirectionalViewMapImages, SIGNAL( triggered() ), this, SLOT( SaveDirectionalViewMapImages() ) );
+ connect( actionAbout, SIGNAL( triggered() ), this, SLOT( About() ) );
+ connect( actionLoadCamera, SIGNAL( triggered() ), this, SLOT( loadCamera() ) );
+ connect( actionSavePSSnapshot, SIGNAL( triggered() ), this, SLOT( PSSnapshot() ) );
+ connect( actionSaveTextSnapshot, SIGNAL( triggered() ), this, SLOT( TextSnapshot() ) );
+ connect( actionControlBindings, SIGNAL( triggered() ), pQGLWidget, SLOT( help() ) );
+}
+
+AppMainWindow::~AppMainWindow() {}
+
+void AppMainWindow::fileOpen()
+{
+ QString s = QFileDialog::getOpenFileName(this,
+ "open file dialog"
+ "Choose a file",
+ g_pController->getModelsDir(),
+ "Scenes (*.3ds *.3DS);;ViewMaps (*." + Config::VIEWMAP_EXTENSION + ")");
+ if ( s.isEmpty() ) {
+ statusBar()->showMessage( "Loading aborted", 2000 );
+ return;
+ }
+
+ QFileInfo fi(s);
+ QString ext = fi.suffix();
+ if ((ext == "3ds") || (ext == "3DS"))
+ {
+ QApplication::setOverrideCursor( Qt::WaitCursor );
+ g_pController->Load3DSFile(s.toAscii().data()); // lunch time...
+ g_pController->setModelsDir(fi.dir().path());
+ QApplication::restoreOverrideCursor();
+ }
+ else if (ext == Config::VIEWMAP_EXTENSION)
+ {
+ QApplication::setOverrideCursor( Qt::WaitCursor );
+ g_pController->LoadViewMapFile(s.toAscii().data()); // ...and now tea time...
+ g_pController->setModelsDir(fi.dir().path());
+ QApplication::restoreOverrideCursor();
+ }
+}
+
+void AppMainWindow::loadCamera()
+{
+ QString s = QFileDialog::getOpenFileName(this,
+ "open file dialog"
+ "Choose a file",
+ g_pController->getModelsDir(),
+ "ViewMaps (*." + Config::VIEWMAP_EXTENSION + ")");
+ if ( s.isEmpty() ) {
+ statusBar()->showMessage( "Loading aborted", 2000 );
+ return;
+ }
+
+ QFileInfo fi(s);
+ QString ext = fi.suffix();
+ if (ext == Config::VIEWMAP_EXTENSION)
+ {
+ QApplication::setOverrideCursor( Qt::WaitCursor );
+ g_pController->LoadViewMapFile(s.toAscii().data(), true);
+ QApplication::restoreOverrideCursor();
+ }
+}
+
+void AppMainWindow::ViewMapFileSave() {
+ QString s = QFileDialog::getSaveFileName(this,
+ "save file dialog"
+ "Choose a file",
+ g_pController->getModelsDir(),
+ "ViewMaps (*." + Config::VIEWMAP_EXTENSION + ")");
+ if (s.isEmpty()) {
+ statusBar()->showMessage( "Saving aborted", 2000 );
+ return;
+ }
+
+ QFileInfo fi(s);
+ QString ext = fi.suffix();
+ if(ext != Config::VIEWMAP_EXTENSION)
+ s += "." + Config::VIEWMAP_EXTENSION;
+
+ QApplication::setOverrideCursor( Qt::WaitCursor );
+ g_pController->setModelsDir(fi.dir().path());
+ g_pController->SaveViewMapFile(s.toAscii().data());
+ QApplication::restoreOverrideCursor();
+}
+
+void AppMainWindow::fileClose()
+{
+ g_pController->CloseFile();
+}
+
+void AppMainWindow::DisplayStylesWindow() {
+ g_pController->ExposeStyleWindow();
+}
+
+void AppMainWindow::DisplayOptionsWindow() {
+ g_pController->ExposeOptionsWindow();
+}
+
+void AppMainWindow::DisplayHelp() {
+ g_pController->ExposeHelpWindow();
+}
+
+void AppMainWindow::About() {
+ g_pController->ExposeAboutWindow();
+}
+
+void AppMainWindow::Snapshot() {
+ g_pController->saveSnapshot();
+}
+
+void AppMainWindow::captureMovie() {
+ g_pController->captureMovie();
+}
+
+void AppMainWindow::ResetInterpreter() {
+ g_pController->resetInterpreter();
+}
+
+//void AppMainWindow::BrutForceSilhouette()
+//{
+// QApplication::setOverrideCursor( Qt::WaitCursor );
+// g_pController->ComputeSilhouette(Controller::BRUT_FORCE);
+// QApplication::restoreOverrideCursor();
+//}
+//
+//void AppMainWindow::AppelSilhouette()
+//{
+// QApplication::setOverrideCursor( Qt::WaitCursor );
+// g_pController->ComputeSilhouette();
+// QApplication::restoreOverrideCursor();
+//}
+
+void AppMainWindow::ComputeViewMap()
+{
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ g_pController->ComputeViewMap();
+ QApplication::restoreOverrideCursor();
+}
+
+void AppMainWindow::SaveDirectionalViewMapImages(){
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ g_pController->saveSteerableViewMapImages();
+ QApplication::restoreOverrideCursor();
+}
+
+void AppMainWindow::ComputeStrokes()
+{
+ g_pController->DrawStrokes();
+}
+
+//void AppMainWindow::InitProgressBar(const char *title, int numSteps)
+//{
+// _ProgressBar = new QProgressDialog(title, 0, numSteps, this, "progress", TRUE);
+// _ProgressBar->show();
+// _ProgressBar->setProgress(0);
+//}
+//
+//void AppMainWindow::SetProgressLabel(const char *label)
+//{
+// if(NULL == _ProgressBar)
+// return;
+// _ProgressBar->setLabelText(label);
+//}
+//
+//void AppMainWindow::SetProgress(int i)
+//{
+// _ProgressBar->setProgress(i);
+// qApp->processEvents();
+//
+// if(i == _ProgressBar->totalSteps())
+// {
+// _ProgressBar->setProgress(_ProgressBar->totalSteps());
+// delete _ProgressBar;
+// _ProgressBar = NULL;
+// }
+//}
+
+void AppMainWindow::DisplayMessage(const char* msg, bool persistent)
+{
+ if(persistent)
+ statusBar()->showMessage( msg);
+ else
+ statusBar()->showMessage( msg, 2000 );
+}
+//void AppMainWindow::toggleSilhouette(bool enabled)
+//{
+// pQGLWidget->ToggleSilhouette(enabled);
+//}
+
+void AppMainWindow::PSSnapshot() {
+ QString s = QFileDialog::getSaveFileName(this,
+ "save file dialog"
+ "Choose a file",
+ g_pController->view()->snapshotFileName(),
+ "Encapsulated Postscript (*.eps)");
+ if (s.isEmpty()) {
+ statusBar()->showMessage( "Saving aborted", 2000 );
+ return;
+ }
+
+ QFileInfo fi(s);
+ QString ext = fi.suffix();
+ if(ext != "eps")
+ s += ".eps" ;
+
+ QApplication::setOverrideCursor( Qt::WaitCursor );
+ g_pController->savePSSnapshot(s);
+ QApplication::restoreOverrideCursor();
+}
+
+void AppMainWindow::TextSnapshot() {
+ QString s = QFileDialog::getSaveFileName(this,
+ "save file dialog"
+ "Choose a file",
+ g_pController->getModelsDir(),
+ "Text File (*.txt)");
+ if (s.isEmpty()) {
+ statusBar()->showMessage( "Saving aborted", 2000 );
+ return;
+ }
+
+ QFileInfo fi(s);
+ QString ext = fi.suffix();
+ if(ext != "txt")
+ s += ".txt" ;
+
+ QApplication::setOverrideCursor( Qt::WaitCursor );
+ g_pController->saveTextSnapshot(s);
+ QApplication::restoreOverrideCursor();
+}
diff --git a/source/blender/freestyle/intern/app/AppMainWindow.h b/source/blender/freestyle/intern/app/AppMainWindow.h
new file mode 100755
index 00000000000..750283f85ba
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppMainWindow.h
@@ -0,0 +1,83 @@
+
+//
+// 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 ARTMAINWINDOW_H
+#define ARTMAINWINDOW_H
+
+#include <QKeyEvent>
+#include <QWidget>
+#include <QPainter>
+#include <QColorGroup>
+#include <QToolBar>
+#include <QMainWindow>
+#include "ui_dir/ui_appmainwindowbase4.h"
+
+using namespace Ui;
+
+class QProgressDialog;
+class AppGLWidget;
+class AppMainWindow : public QMainWindow, public AppMainWindowBase
+{
+ Q_OBJECT
+
+public:
+
+ AppMainWindow(QWidget *parent = 0, const char *name = 0, Qt::WindowFlags f = Qt::Window);
+ ~AppMainWindow();
+
+ QToolBar *pTools;
+
+public slots:
+ virtual void fileOpen();
+ virtual void fileClose();
+ virtual void loadCamera();
+ virtual void DisplayStylesWindow();
+ virtual void DisplayOptionsWindow();
+ virtual void DisplayHelp();
+ virtual void About();
+ virtual void ViewMapFileSave();
+ // virtual void AppelSilhouette();
+ // virtual void BrutForceSilhouette();
+ virtual void ComputeViewMap();
+ virtual void SaveDirectionalViewMapImages();
+ virtual void ComputeStrokes();
+ virtual void Snapshot();
+ virtual void captureMovie();
+ virtual void ResetInterpreter();
+ virtual void PSSnapshot();
+ virtual void TextSnapshot();
+
+public:
+ // void InitProgressBar(const char *title, int numSteps)
+ ;
+ // void SetProgressLabel(const char *label);
+ // void SetProgress(int i);
+ //
+ void DisplayMessage(const char* msg, bool persistent = false);
+
+ QProgressDialog * qtProgressDialog() {return _ProgressBar;}
+ AppGLWidget * pQGLWidget;
+
+private:
+ QProgressDialog* _ProgressBar;
+};
+
+
+#endif
diff --git a/source/blender/freestyle/intern/app/AppOptionsWindow.cpp b/source/blender/freestyle/intern/app/AppOptionsWindow.cpp
new file mode 100755
index 00000000000..6c3dc9a83aa
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppOptionsWindow.cpp
@@ -0,0 +1,410 @@
+
+//
+// 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 <QCheckBox>
+#include <QLineEdit>
+#include <QFileDialog>
+#include <QString>
+#include <QStringList>
+#include <QListWidgetItem>
+#include "../stroke/StrokeRenderer.h"
+#include "AppConfig.h"
+#include "Controller.h"
+#include "../view_map/ViewMapIO.h"
+#include "AppOptionsWindow.h"
+
+AppOptionsWindow::AppOptionsWindow(QWidget *parent, const char *name, bool modal, Qt::WFlags fl)
+: QDialog(parent, fl) { // parent, name, modal, fl) {
+
+ setupUi(this);
+ const QString sep(Config::DIR_SEP.c_str());
+ QString filename;
+
+ // Create a ConfigIO object
+ filename = Config::Path::getInstance()->getHomeDir() + sep + Config::OPTIONS_DIR + sep + Config::OPTIONS_FILE;
+ _options = new ConfigIO(filename, Config::APPLICATION_NAME + "Options");
+ _options->loadFile();
+
+ // Set the widgets to correct values
+
+ // -> Directories tab
+ QString str;
+ Config::Path * cpath = Config::Path::getInstance();
+ if (_options->getValue("default_path/models/path", str))
+ str = cpath->getModelsPath();
+ modelsPathLineEdit->setText(str);
+ if (_options->getValue("default_path/patterns/path", str))
+ str = cpath->getPatternsPath();
+ patternsPathLineEdit->setText(str);
+ if (_options->getValue("default_path/brushes/path", str))
+ str = cpath->getBrushesPath();
+ brushesPathLineEdit->setText(str);
+ if (_options->getValue("default_path/python/path", str))
+ str = cpath->getPythonPath();
+ pythonPathLineEdit->setText(str);
+
+ // -> Papers Textures tab
+ unsigned papers_nb;
+ QStringList sl;
+ if (_options->getValue("papers/nb", papers_nb)) {
+ sl.push_back(cpath->getPapersDir() + Config::DEFAULT_PAPER_TEXTURE);
+ } else {
+ for (unsigned i = 0; i < papers_nb; i++) {
+ QString path;
+ QTextStream(&path) << "papers/texture" << i << "/filename";
+ _options->getValue(path, str);
+ paperTexturesList->insertItem(paperTexturesList->count(), str);
+ }
+ }
+
+
+ // -> Help tab
+ if (_options->getValue("default_browser/cmd", str))
+ str = cpath->getBrowserCmd();
+ browserCmdLineEdit->setText(str);
+ if (_options->getValue("default_path/help/index", str))
+ str = cpath->getHelpIndexpath();
+ helpIndexPathLineEdit->setText(str);
+
+ // -> Misc tab
+ bool b;
+ if (_options->getValue("default_viewmap_format/float_vectors", b))
+ b = false;
+ asFloatCheckBox->setChecked(b);
+ if (_options->getValue("default_viewmap_format/no_occluders", b))
+ b = false;
+ noOccluderListCheckBox->setChecked(b);
+ if (_options->getValue("default_viewmap_format/compute_steerable", b))
+ b = false;
+ steerableViewMapCheckBox->setChecked(b);
+ if (_options->getValue("default_visibility/exhaustive_computation", b))
+ b = true;
+ qiCheckBox->setChecked(b);
+ if (_options->getValue("default_drawing_buffers/back_buffer", b))
+ b = true;
+ backBufferCheckBox->setChecked(b);
+ if (_options->getValue("default_drawing_buffers/front_buffer", b))
+ b = false;
+ frontBufferCheckBox->setChecked(b);
+ real r;
+ if (_options->getValue("default_ridges/sphere_radius", r))
+ r = Config::DEFAULT_SPHERE_RADIUS;
+ sphereRadiusLineEdit->setText(QString(QString::number(r)));
+ if (_options->getValue("default_ridges/enable", b))
+ b = false;
+ ridgeValleyCheckBox->setChecked(b);
+ if (_options->getValue("default_suggestive_contours/enable", b))
+ b = false;
+ suggestiveContoursCheckBox->setChecked(b);
+ if (_options->getValue("default_suggestive_contours/dkr_epsilon", r))
+ r = Config::DEFAULT_DKR_EPSILON;
+ krEpsilonLineEdit->setText(QString(QString::number(r)));
+
+ // Propagate changes
+ Propagate();
+
+ // signals and slots connections
+ connect( okButton, SIGNAL( clicked() ), this, SLOT( Ok() ) );
+ connect( applyButton, SIGNAL( clicked() ), this, SLOT( Apply() ) );
+ connect( closeButton, SIGNAL( clicked() ), this, SLOT( Cancel() ) );
+ connect( patternsPathAddButton, SIGNAL( clicked() ), this, SLOT( PatternsAdd() ) );
+ connect( modelPathAddButton, SIGNAL( clicked() ), this, SLOT( ModelsAdd() ) );
+ connect( addPaperTextureButton, SIGNAL( clicked() ), this, SLOT( PaperAdd() ) );
+ connect( removePaperTextureButton, SIGNAL( clicked() ), this, SLOT( PaperRemove() ) );
+ connect( moveUpPaperTextureButton, SIGNAL( clicked() ), this, SLOT( PaperUp() ) );
+ connect( moveDownPaperTextureButton, SIGNAL( clicked() ), this, SLOT( PaperDown() ) );
+ connect( clearPaperTextureButton, SIGNAL( clicked() ), this, SLOT( PaperClear() ) );
+ connect( pythonPathAddButton, SIGNAL( clicked() ), this, SLOT( PythonAdd() ) );
+ connect( helpIndexPathButton, SIGNAL( clicked() ), this, SLOT( HelpAdd() ) );
+ connect( brushesPathAddButton, SIGNAL( clicked() ), this, SLOT( BrushesAdd() ) );
+}
+
+AppOptionsWindow::~AppOptionsWindow() {
+ delete _options;
+}
+
+void AppOptionsWindow::Propagate() {
+
+ // Directories
+ ViewMapIO::Options::setModelsPath((const char*)modelsPathLineEdit->text().toAscii().data());
+ PythonInterpreter::Options::setPythonPath((const char*)pythonPathLineEdit->text().toAscii().data());
+ TextureManager::Options::setPatternsPath((const char*)patternsPathLineEdit->text().toAscii().data());
+ TextureManager::Options::setBrushesPath((const char*)brushesPathLineEdit->text().toAscii().data());
+ g_pController->setBrowserCmd(browserCmdLineEdit->text());
+ g_pController->setHelpIndex(helpIndexPathLineEdit->text());
+
+ // ViewMap Format
+ if (asFloatCheckBox->isChecked())
+ ViewMapIO::Options::addFlags(ViewMapIO::Options::FLOAT_VECTORS);
+ else
+ ViewMapIO::Options::rmFlags(ViewMapIO::Options::FLOAT_VECTORS);
+ if (noOccluderListCheckBox->isChecked())
+ ViewMapIO::Options::addFlags(ViewMapIO::Options::NO_OCCLUDERS);
+ else
+ ViewMapIO::Options::rmFlags(ViewMapIO::Options::NO_OCCLUDERS);
+ g_pController->setComputeSteerableViewMapFlag(steerableViewMapCheckBox->isChecked());
+
+ // Visibility
+ if (qiCheckBox->isChecked())
+ g_pController->setQuantitativeInvisibility(true);
+ else
+ g_pController->setQuantitativeInvisibility(false);
+
+ // Papers Textures
+ vector<string> sl;
+ for (unsigned i = 0; i < paperTexturesList->count(); i++) {
+ sl.push_back(paperTexturesList->item(i)->text().toAscii().constData());
+ }
+ TextureManager::Options::setPaperTextures(sl);
+
+ // Drawing Buffers
+ if (frontBufferCheckBox->isChecked())
+ g_pController->setFrontBufferFlag(true);
+ else
+ g_pController->setFrontBufferFlag(false);
+ if (backBufferCheckBox->isChecked())
+ g_pController->setBackBufferFlag(true);
+ else
+ g_pController->setBackBufferFlag(false);
+
+ // Ridges and Valleys
+ g_pController->setComputeRidgesAndValleysFlag(ridgeValleyCheckBox->isChecked());
+ // Suggestive Contours
+ g_pController->setComputeSuggestiveContoursFlag(suggestiveContoursCheckBox->isChecked());
+ bool ok;
+ real r = sphereRadiusLineEdit->text().toFloat(&ok);
+ if(ok)
+ g_pController->setSphereRadius(r);
+ else
+ sphereRadiusLineEdit->setText(QString(QString::number(g_pController->getSphereRadius())));
+ r = krEpsilonLineEdit->text().toFloat(&ok);
+ if(ok)
+ g_pController->setSuggestiveContourKrDerivativeEpsilon(r);
+ else
+ krEpsilonLineEdit->setText(QString(QString::number(g_pController->getSuggestiveContourKrDerivativeEpsilon())));
+}
+
+void AppOptionsWindow::Ok() {
+ Apply();
+ close();
+}
+
+void AppOptionsWindow::Apply() {
+
+ // Propagate changes
+ Propagate();
+
+ // Update values of the Options DOM Tree accordingly
+ _options->setValue("default_path/models/path", modelsPathLineEdit->text());
+ _options->setValue("default_path/patterns/path", patternsPathLineEdit->text());
+ _options->setValue("default_path/brushes/path", brushesPathLineEdit->text());
+ _options->setValue("default_path/python/path", pythonPathLineEdit->text());
+ _options->setValue("default_browser/cmd", browserCmdLineEdit->text());
+ _options->setValue("default_path/help/index", helpIndexPathLineEdit->text());
+ _options->setValue("default_viewmap_format/float_vectors", asFloatCheckBox->isChecked());
+ _options->setValue("default_viewmap_format/no_occluders", noOccluderListCheckBox->isChecked());
+ _options->setValue("default_visibility/exhaustive_computation", qiCheckBox->isChecked());
+ _options->setValue("default_drawing_buffers/front_buffer", frontBufferCheckBox->isChecked());
+ _options->setValue("default_drawing_buffers/back_buffer", backBufferCheckBox->isChecked());
+
+ // -> Papers Textures tab
+ unsigned papers_nb = paperTexturesList->count();
+ _options->setValue("papers/nb", papers_nb);
+ for (unsigned i = 0; i < papers_nb; i++) {
+ QString path;
+ QTextStream(&path) << "papers/texture" << i << "/filename";
+ _options->setValue(path, paperTexturesList->item(i)->text());
+ }
+
+ // -> Help tab
+ _options->setValue("default_browser/cmd", browserCmdLineEdit->text());
+ _options->setValue("default_path/help/index", helpIndexPathLineEdit->text());
+
+ // -> Misc tab
+ _options->setValue("default_viewmap_format/float_vectors", asFloatCheckBox->isChecked());
+ _options->setValue("default_viewmap_format/no_occluders", noOccluderListCheckBox->isChecked());
+ _options->setValue("default_viewmap_format/compute_steerable", steerableViewMapCheckBox->isChecked());
+ _options->setValue("default_visibility/exhaustive_computation", qiCheckBox->isChecked());
+ _options->setValue("default_drawing_buffers/back_buffer", backBufferCheckBox->isChecked());
+ _options->setValue("default_drawing_buffers/front_buffer", frontBufferCheckBox->isChecked());
+ _options->setValue("default_ridges/enable", ridgeValleyCheckBox->isChecked());
+ _options->setValue("default_suggestive_contours/enable", suggestiveContoursCheckBox->isChecked());
+ bool ok;
+ real r = sphereRadiusLineEdit->text().toFloat(&ok);
+ if(!ok)
+ r = Config::DEFAULT_SPHERE_RADIUS;
+ _options->setValue("default_ridges/sphere_radius", r);
+ r = krEpsilonLineEdit->text().toFloat(&ok);
+ if(!ok)
+ r = Config::DEFAULT_DKR_EPSILON;
+ _options->setValue("default_suggestive_contours/dkr_epsilon", r);
+
+ // Save options to disk
+ _options->saveFile();
+}
+
+void AppOptionsWindow::Cancel() {
+
+ // Directories
+ QString qstr;
+ qstr = ViewMapIO::Options::getModelsPath().c_str();
+ modelsPathLineEdit->setText(qstr);
+ qstr = PythonInterpreter::Options::getPythonPath().c_str();
+ pythonPathLineEdit->setText(qstr);
+ qstr = TextureManager::Options::getPatternsPath().c_str();
+ patternsPathLineEdit->setText(qstr);
+ qstr = TextureManager::Options::getBrushesPath().c_str();
+ brushesPathLineEdit->setText(qstr);
+ qstr = g_pController->getBrowserCmd();
+ browserCmdLineEdit->setText(qstr);
+ qstr = g_pController->getHelpIndex();
+ helpIndexPathLineEdit->setText(qstr);
+
+ // ViewMap Format
+ updateViewMapFormat();
+ steerableViewMapCheckBox->setChecked(g_pController->getComputeSteerableViewMapFlag());
+
+ // Visibility
+ qiCheckBox->setChecked(g_pController->getQuantitativeInvisibility());
+
+ // Drawing buffers
+ frontBufferCheckBox->setChecked(g_pController->getFrontBufferFlag());
+ backBufferCheckBox->setChecked(g_pController->getBackBufferFlag());
+
+ // Ridges and Valleys
+ ridgeValleyCheckBox->setChecked(g_pController->getComputeRidgesAndValleysFlag());
+ // suggestive contours
+ suggestiveContoursCheckBox->setChecked(g_pController->getComputeSuggestiveContoursFlag());
+ sphereRadiusLineEdit->setText(QString::number(g_pController->getSphereRadius()));
+ krEpsilonLineEdit->setText(QString(QString::number(g_pController->getSuggestiveContourKrDerivativeEpsilon())));
+
+ close();
+}
+
+void AppOptionsWindow::updateViewMapFormat() {
+ asFloatCheckBox->setChecked(ViewMapIO::Options::getFlags() & ViewMapIO::Options::FLOAT_VECTORS);
+ noOccluderListCheckBox->setChecked(ViewMapIO::Options::getFlags() & ViewMapIO::Options::NO_OCCLUDERS);
+}
+
+void AppOptionsWindow::ModelsAdd() {
+ QString s = modelsPathLineEdit->text();
+ QString new_s = DirDialog();
+ if (new_s.isEmpty())
+ return;
+ if (!s.isEmpty())
+ s += Config::PATH_SEP.c_str();
+ s += new_s;
+ modelsPathLineEdit->setText(s);
+}
+
+void AppOptionsWindow::PatternsAdd() {
+ QString s = patternsPathLineEdit->text();
+ QString new_s = DirDialog();
+ if (new_s.isEmpty())
+ return;
+ if (!s.isEmpty())
+ s += Config::PATH_SEP.c_str();
+ s += new_s;
+ patternsPathLineEdit->setText(s);
+}
+
+void AppOptionsWindow::BrushesAdd() {
+ QString s = brushesPathLineEdit->text();
+ QString new_s = DirDialog();
+ if (new_s.isEmpty())
+ return;
+ if (!s.isEmpty())
+ s += Config::PATH_SEP.c_str();
+ s += new_s;
+ brushesPathLineEdit->setText(s);
+}
+
+void AppOptionsWindow::PythonAdd() {
+ QString s = pythonPathLineEdit->text();
+ QString new_s = DirDialog();
+ if (new_s.isEmpty())
+ return;
+ if (!s.isEmpty())
+ s += Config::PATH_SEP.c_str();
+ s += new_s;
+ pythonPathLineEdit->setText(s);
+}
+
+void AppOptionsWindow::HelpAdd() {
+ QString s = QFileDialog::getOpenFileName((QWidget *)this,
+ "Open file dialog"
+ "Choose a file",
+ g_pController->getHelpIndex(),
+ "HTML files (*.html *.htm)");
+ if (s.isEmpty())
+ return;
+ helpIndexPathLineEdit->setText(s);
+}
+
+QString AppOptionsWindow::DirDialog() {
+ QString s = QFileDialog::getExistingDirectory((QWidget *)this,
+ "get existing directory"
+ "Choose a directory",
+ ".",
+ QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);
+ return s;
+}
+
+void AppOptionsWindow::PaperAdd() {
+ QStringList sl = QFileDialog::getOpenFileNames((QWidget *)this,
+ "open files dialog"
+ "Choose a file",
+ g_pController->getPapersDir(),
+ "Images (*.bmp *.png *.jpg *.xpm)");
+ paperTexturesList->insertItems(paperTexturesList->count(), sl);
+}
+
+void AppOptionsWindow::PaperRemove() {
+ paperTexturesList->takeItem(paperTexturesList->currentRow());
+}
+
+void AppOptionsWindow::PaperUp() {
+ int current = paperTexturesList->currentRow();
+ if (current < 1)
+ return;
+ QString s = paperTexturesList->currentItem()->text();
+ paperTexturesList->item(current)->setText(paperTexturesList->item(current - 1)->text());
+ paperTexturesList->item(current - 1)->setText(s);
+ paperTexturesList->setCurrentRow(current - 1);
+}
+
+void AppOptionsWindow::PaperDown() {
+ int current = paperTexturesList->currentRow();
+ if (current > paperTexturesList->count() - 2)
+ return;
+ QString s = paperTexturesList->currentItem()->text();
+ paperTexturesList->item(current)->setText(paperTexturesList->item(current + 1)->text());
+ paperTexturesList->item(current + 1)->setText(s);
+ paperTexturesList->setCurrentRow(current + 1);
+}
+
+void AppOptionsWindow::PaperClear() {
+ paperTexturesList->clear();
+}
+
diff --git a/source/blender/freestyle/intern/app/AppOptionsWindow.h b/source/blender/freestyle/intern/app/AppOptionsWindow.h
new file mode 100755
index 00000000000..aaa964739a6
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppOptionsWindow.h
@@ -0,0 +1,74 @@
+//
+// Filename : AppOptionsWindow.h
+// Author : Emmanuel Turquin, Stephane Grabli
+// Purpose : Class to define the options window
+// Date of creation : 27/01/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 ARTOPTIONSWINDOW_H
+#define ARTOPTIONSWINDOW_H
+
+#include "ConfigIO.h"
+#include "ui_dir/ui_optionswindow4.h"
+
+using namespace Ui;
+
+class AppOptionsWindow : public QDialog, public OptionsWindow
+{
+ Q_OBJECT
+
+public:
+
+ AppOptionsWindow(QWidget *parent = 0, const char *name = 0, bool modal = FALSE, Qt::WFlags fl = 0);
+ ~AppOptionsWindow();
+
+ virtual void updateViewMapFormat();
+
+public slots:
+
+ virtual void Ok();
+ virtual void Apply();
+ virtual void Cancel();
+
+ virtual void ModelsAdd();
+ virtual void PatternsAdd();
+ virtual void BrushesAdd();
+ virtual void PythonAdd();
+ virtual void HelpAdd();
+
+ virtual void PaperAdd();
+ virtual void PaperRemove();
+ virtual void PaperUp();
+ virtual void PaperDown();
+ virtual void PaperClear();
+
+ private:
+
+ virtual QString DirDialog();
+ virtual void Propagate();
+
+ ConfigIO* _options;
+};
+
+#endif // ARTOPTIONSWINDOW_H
diff --git a/source/blender/freestyle/intern/app/AppProgressBar.cpp b/source/blender/freestyle/intern/app/AppProgressBar.cpp
new file mode 100755
index 00000000000..a4d18d07dd3
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppProgressBar.cpp
@@ -0,0 +1,78 @@
+
+//
+// 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 <qprogressdialog.h>
+#include <qapplication.h>
+#include "AppProgressBar.h"
+
+AppProgressBar::AppProgressBar()
+ : ProgressBar()
+{
+ _qtProgressBar = 0;
+}
+
+void AppProgressBar::reset()
+{
+ ProgressBar::reset();
+ if(NULL == _qtProgressBar)
+ return;
+
+ _qtProgressBar->reset();
+ _qtProgressBar->show();
+}
+
+void AppProgressBar::setTotalSteps(unsigned n)
+{
+ ProgressBar::setTotalSteps(n);
+ if(NULL == _qtProgressBar)
+ return;
+
+ _qtProgressBar->setRange(0,_numtotalsteps);
+}
+
+void AppProgressBar::setProgress(unsigned i)
+{
+ if(i > _numtotalsteps)
+ return;
+
+ ProgressBar::setProgress(i);
+ if(NULL == _qtProgressBar)
+ return;
+
+ _qtProgressBar->setValue(_progress);
+ qApp->processEvents();
+
+ if(i == _numtotalsteps)
+ {
+ _qtProgressBar->setValue(_numtotalsteps);
+
+ _qtProgressBar->reset();
+ ProgressBar::reset();
+ _qtProgressBar->hide();
+ }
+}
+
+void AppProgressBar::setLabelText(const string& label)
+{
+ ProgressBar::setLabelText(label);
+ if (NULL == _qtProgressBar)
+ return;
+ _qtProgressBar->setLabelText(_label.c_str());
+}
diff --git a/source/blender/freestyle/intern/app/AppProgressBar.h b/source/blender/freestyle/intern/app/AppProgressBar.h
new file mode 100755
index 00000000000..09cc500a981
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppProgressBar.h
@@ -0,0 +1,55 @@
+#ifndef ARTPROGRESSBAR_H
+#define ARTPROGRESSBAR_H
+
+//
+//
+// FileName : AppProgressBar.h
+// Author : Stephane Grabli
+// Purpose : Class to define the App progress bar
+// Date Of Creation : 27/08/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.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include "../system/ProgressBar.h"
+
+class QProgressDialog;
+class AppProgressBar : public ProgressBar
+{
+public:
+ AppProgressBar();
+
+ virtual ~AppProgressBar() {}
+
+ virtual void reset();
+ virtual void setTotalSteps(unsigned n);
+ virtual void setProgress(unsigned i);
+ virtual void setLabelText(const string& text) ;
+
+ void setQTProgressBar(QProgressDialog* qtBar) {_qtProgressBar = qtBar;}
+
+ QProgressDialog * getQTProgressBar() {return _qtProgressBar;}
+
+private:
+ QProgressDialog *_qtProgressBar;
+};
+
+#endif
diff --git a/source/blender/freestyle/intern/app/AppStyleWindow.cpp b/source/blender/freestyle/intern/app/AppStyleWindow.cpp
new file mode 100755
index 00000000000..d8be753b498
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppStyleWindow.cpp
@@ -0,0 +1,366 @@
+
+//
+// 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 <fstream>
+#include <QCursor>
+#include <QApplication>
+#include <QFileDialog>
+#include <QHeaderView>
+#include <QString>
+#include "AppStyleWindow.h"
+#include "../stroke/Canvas.h"
+#include "../stroke/StyleModule.h"
+#include "Controller.h"
+#include "AppInteractiveShaderWindow.h"
+#include "AppConfig.h"
+
+AppStyleWindow::AppStyleWindow(QWidget* parent /* = 0 */, const char* name /* = 0 */, Qt::WFlags fl /* = 0 */)
+ : QDialog(parent, fl)
+{
+ // QDialog *widget = new QDialog(parent);
+ setupUi(this);
+ PlayList->setShowGrid(false);
+ PlayList->verticalHeader()->setVisible(false);
+ PlayList->horizontalHeader()->setClickable(false);
+ PlayList->setSelectionBehavior(QAbstractItemView::SelectRows);
+ PlayList->setSelectionMode(QAbstractItemView::SingleSelection);
+ PlayList->setColumnCount(5);
+ PlayList->setColumnWidth(0, 37);
+ PlayList->setColumnWidth(1, width() - 98);
+ PlayList->setColumnWidth(2, 37);
+ PlayList->hideColumn(3);
+ PlayList->hideColumn(4);
+ PlayList->setRowCount(0);
+ //PlayList->setsetLeftMargin(0);
+ PlayList->setHorizontalHeaderLabels((QStringList() << "Disp." << "Style Modules" << "Mod."));
+ _pInteractiveShaderWindow = new AppInteractiveShaderWindow(this);
+ _pInteractiveShaderWindow->hide();
+ QString projectDir(Config::Path::getInstance()->getProjectDir());
+ _mod0_image = new QPixmap(QString::fromUtf8(":/icons/icons/mod0.png"));
+ _mod1_image = new QPixmap(QString::fromUtf8(":/icons/icons/mod1.png"));
+ _disp0_image = new QPixmap(QString::fromUtf8(":/icons/icons/eye0.png"));
+ _disp1_image = new QPixmap(QString::fromUtf8(":/icons/icons/eye1.png"));
+
+ connect(_pInteractiveShaderWindow, SIGNAL(save()), SLOT(fileSave()));
+ // signals and slots connections
+ connect( addButton, SIGNAL( clicked() ), this, SLOT( Add() ) );
+ connect( removeButton, SIGNAL( clicked() ), this, SLOT( Remove() ) );
+ connect( PlayList, SIGNAL( cellDoubleClicked(int,int) ), this, SLOT( Display(int,int) ) );
+ connect( PlayList, SIGNAL( cellClicked(int,int) ), this, SLOT( ToggleLayer(int,int) ) );
+ connect( clearButton, SIGNAL( clicked() ), this, SLOT( Clear() ) );
+ connect( saveButton, SIGNAL( clicked() ), this, SLOT( SaveList() ) );
+ connect( moveUpButton, SIGNAL( clicked() ), this, SLOT( Up() ) );
+ connect( moveDownButton, SIGNAL( clicked() ), this, SLOT( Down() ) );
+ connect( editButton, SIGNAL( clicked() ), this, SLOT( Edit() ) );
+ connect( closeButton, SIGNAL( clicked() ), this, SLOT( Close() ) );
+}
+
+AppStyleWindow::~AppStyleWindow()
+{
+ delete _mod0_image;
+ delete _mod1_image;
+ delete _disp0_image;
+ delete _disp1_image;
+}
+
+void AppStyleWindow::Add(const char* iFileName, bool iDisp) {
+ //Add the item in the view box
+ //PlayList->insertItem(fi.fileName());
+ // PlayList->insertItem(s);
+ int currentRow;
+ QFileInfo fi(iFileName);
+ if(0 == PlayList->rowCount())
+ {
+ currentRow = -1;
+ }
+ else
+ {
+ currentRow = PlayList->currentRow();
+ }
+ PlayList->insertRow(currentRow+1);
+ for(int i=0; i< PlayList->rowCount(); ++i){
+ PlayList->setRowHeight(i, 20);
+ }
+ //PlayList->setRowHeight(currentRow + 1, 20);
+
+ // eye item
+ QTableWidgetItem * eye_item = new QTableWidgetItem;
+ eye_item->setFlags(Qt::ItemIsEnabled);
+ PlayList->setItem(currentRow + 1, 0, eye_item);
+ // style module name item
+ QTableWidgetItem * style_module_name_item = new QTableWidgetItem(fi.fileName());
+ style_module_name_item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
+ PlayList->setItem(currentRow + 1, 1, style_module_name_item);
+ PlayList->setItem(currentRow + 1, 3, new QTableWidgetItem(iFileName));
+ // refresh item
+ QTableWidgetItem * refresh_item = new QTableWidgetItem;
+ refresh_item->setFlags(Qt::ItemIsEnabled);
+ PlayList->setItem(currentRow + 1, 2, refresh_item);
+
+ setModified(currentRow + 1, true);
+ QTableWidgetItem *checkItem = new QTableWidgetItem;
+ checkItem->setFlags(Qt::ItemIsUserCheckable);
+ if(iDisp)
+ checkItem->setCheckState(Qt::Checked);
+ else
+ checkItem->setCheckState(Qt::Unchecked);
+ PlayList->setItem(currentRow + 1, 4, checkItem);
+ setChecked(currentRow + 1, iDisp);
+ PlayList->setCurrentCell(currentRow + 1, 1);
+ //PlayList->setRangeSelected(QTableWidgetSelectionRange( currentRow+1, 0, currentRow+1, 4), true);
+ QString text = (PlayList->item(currentRow + 1, 3))->text();
+ PlayList->takeVerticalHeaderItem(currentRow + 1);
+ _pInteractiveShaderWindow->setCurrentShaderRow(currentRow + 1);
+ _pInteractiveShaderWindow->DisplayShader(text);
+
+ // Load the shader in memory and add it to the
+ // canvas list
+ g_pController->InsertStyleModule(currentRow + 1, iFileName);
+ g_pController->toggleLayer(currentRow + 1, iDisp);
+}
+
+void AppStyleWindow::AddList(const char* iFileName) {
+ ifstream ifs(iFileName);
+ if (!ifs.is_open()) {
+ cerr << "Error: Cannot load this file" << endl;
+ return;
+ }
+ QFileInfo fi(iFileName);
+ char tmp_buffer[256];
+ string s;
+ bool disp = true;
+ while (!ifs.eof()) {
+ ifs.getline(tmp_buffer, 255);
+ if (!tmp_buffer[0] || tmp_buffer[0] == '#')
+ continue;
+ if (tmp_buffer[0] == '0')
+ disp = false;
+ else
+ disp = true;
+ s = (const char*)fi.dir().path().toAscii().data();
+ s += Config::DIR_SEP;
+ s += tmp_buffer + 1;
+ ifstream test(s.c_str(), ios::binary);
+ if (!test.is_open()) {
+ cerr << "Error: Cannot load \"" << tmp_buffer + 1 << "\"" << endl;
+ continue;
+ }
+ Add(s.c_str(), disp);
+ }
+}
+
+void AppStyleWindow::SaveList() {
+ QString s = QFileDialog::getSaveFileName(
+ this,
+ "Save file dialog"
+ "Choose a file",
+ g_pController->getModulesDir(),
+ "Style modules lists (*." + Config::STYLE_MODULES_LIST_EXTENSION + ")");
+
+ if (s.isEmpty())
+ return;
+ QFileInfo fi( s );
+ QString ext = fi.suffix();
+ if (ext != Config::STYLE_MODULES_LIST_EXTENSION)
+ s += "." + Config::STYLE_MODULES_LIST_EXTENSION;
+ ofstream ofs(s.toAscii().data(), ios::binary);
+ if (!ofs.is_open()) {
+ cerr << "Error: Cannot save this file" << endl;
+ return;
+ }
+
+ QTableWidgetItem *checkItem;
+ for (unsigned i = 0 ; i < PlayList->rowCount(); i++) {
+ checkItem = PlayList->item(i, 4);
+ ofs << ((checkItem->checkState() == Qt::Checked) ? '1' : '0');
+ ofs << PlayList->item(i, 1)->text().toAscii().data() << endl;
+ }
+ g_pController->setModulesDir(fi.dir().path());
+ cout << "Style modules list saved" << endl;
+}
+
+void AppStyleWindow::Add()
+{
+ // Load Module
+ QString s = QFileDialog::getOpenFileName(this,
+ "Open file dialog"
+ "Choose a file",
+ g_pController->getModulesDir(),
+ "Style modules (*." + Config::STYLE_MODULE_EXTENSION + ")"
+ ";;"
+ "Style modules lists (*." + Config::STYLE_MODULES_LIST_EXTENSION + ")");
+
+ QFileInfo fi( s );
+ QString ext = fi.suffix(); // ext is taken after the last dot.
+
+ if (ext == Config::STYLE_MODULE_EXTENSION) {
+ g_pController->setModulesDir(fi.dir().path());
+ Add(s.toAscii().data());
+ }
+ else if (ext == Config::STYLE_MODULES_LIST_EXTENSION) {
+ g_pController->setModulesDir(fi.dir().path());
+ AddList(s.toAscii().data());
+ }
+}
+
+void AppStyleWindow::Remove()
+{
+ // Remove the selected item
+ g_pController->RemoveStyleModule(PlayList->currentRow());
+ PlayList->removeRow(PlayList->currentRow());
+ _pInteractiveShaderWindow->fileClose();
+}
+
+void AppStyleWindow::Clear()
+{
+ g_pController->Clear();
+ for (int i = PlayList->rowCount() - 1; i >= 0; i--)
+ PlayList->removeRow(i);
+ _pInteractiveShaderWindow->fileClose();
+}
+
+void AppStyleWindow::ExposeInteractiveShader()
+{
+ _pInteractiveShaderWindow->show();
+ //_pInteractiveShaderWindow->Load();
+}
+
+void AppStyleWindow::setModified(unsigned row, bool mod) {
+ if (mod) {
+ PlayList->item(row, 2)->setIcon(QIcon(*_mod1_image));
+ return;
+ }
+ Canvas* canvas = Canvas::getInstance();
+ StyleModule* sm = canvas->getCurrentStyleModule();
+ if (sm && sm->getAlwaysRefresh())
+ return;
+ PlayList->item(row, 2)->setIcon(QIcon(*_mod0_image));
+}
+
+void AppStyleWindow::setChecked(unsigned row, bool check) {
+ if (check)
+ PlayList->item(row, 0)->setIcon(QIcon(*_disp1_image));
+ else
+ PlayList->item(row, 0)->setIcon(QIcon(*_disp0_image));
+}
+
+void AppStyleWindow::Edit() {
+ if(PlayList->rowCount() == 0)
+ return;
+
+ int currentRow = PlayList->currentRow();
+
+ ExposeInteractiveShader();
+ QString text = (PlayList->item(currentRow, 3)->text());
+ _pInteractiveShaderWindow->setCurrentShaderRow(currentRow);
+ _pInteractiveShaderWindow->DisplayShader(text);
+}
+
+void AppStyleWindow::Display( int row, int col ) {
+ if(col != 1)
+ return;
+
+ Edit();
+}
+
+void AppStyleWindow::ToggleLayer(int row, int col)
+{
+ if(0 == PlayList->rowCount())
+ return;
+
+ if(col != 0)
+ return;
+
+ QTableWidgetItem *checkItem = PlayList->item(row, 4);
+ if(checkItem->flags() != Qt::ItemIsUserCheckable)
+ return;
+
+ bool isChecked;
+ if(checkItem->checkState() == Qt::Checked){
+ checkItem->setCheckState(Qt::Unchecked);
+ isChecked = false;
+ }else{
+ checkItem->setCheckState(Qt::Checked);
+ isChecked = true;
+ }
+ g_pController->toggleLayer(row, isChecked);
+ setChecked(row, isChecked);
+}
+
+void AppStyleWindow::Up() {
+ int current = PlayList->currentRow();
+ if (current > 0) {
+ SwapShaders(current, current - 1);
+ PlayList->clearSelection();
+
+ PlayList->setRangeSelected(QTableWidgetSelectionRange( current-1, 0, current-1, 4), true);
+ PlayList->setCurrentCell(current-1, 1);
+ g_pController->updateCausalStyleModules(current - 1);
+ current = current-1;
+ }
+}
+
+void AppStyleWindow::Down() {
+ int current = PlayList->currentRow();
+ if (current < PlayList->rowCount() - 1) {
+ SwapShaders(current, current + 1);
+ PlayList->clearSelection();
+
+ PlayList->setRangeSelected(QTableWidgetSelectionRange( current+1, 0, current+1, 4), true);
+ PlayList->setCurrentCell(current+1, 1);
+
+ g_pController->updateCausalStyleModules(current);
+ current = current +1;
+ }
+}
+
+void AppStyleWindow::fileSave() {
+ int current = _pInteractiveShaderWindow->getCurrentShaderRow();
+ QString text = (PlayList->item(current, 3)->text());
+ g_pController->ReloadStyleModule(current, text.toAscii().data());
+ QTableWidgetItem *checkItem = PlayList->item(current, 4);
+ bool isChecked = (checkItem->checkState() == Qt::Checked) ? true : false;
+ g_pController->toggleLayer(current, isChecked);
+}
+
+void AppStyleWindow::resetModified(bool iMod)
+{
+ for(int i=0; i < PlayList->rowCount(); i++)
+ {
+ setModified(i,iMod);
+ }
+}
+
+void AppStyleWindow::SwapShaders(int i1, int i2) {
+ g_pController->SwapStyleModules(i1, i2);
+ //PlayList->swapRows(i1, i2);
+ QTableWidgetItem *first_row_items[5];
+ QTableWidgetItem *second_row_items[5];
+ int i;
+ for(i=0;i<5;++i){
+ first_row_items[i] = PlayList->takeItem(i1, i);
+ second_row_items[i] = PlayList->takeItem(i2, i);
+ }
+ for(i=0;i<5;++i){
+ PlayList->setItem(i1, i, second_row_items[i]);
+ PlayList->setItem(i2, i, first_row_items[i]);
+ }
+}
diff --git a/source/blender/freestyle/intern/app/AppStyleWindow.h b/source/blender/freestyle/intern/app/AppStyleWindow.h
new file mode 100755
index 00000000000..a9339abf9c8
--- /dev/null
+++ b/source/blender/freestyle/intern/app/AppStyleWindow.h
@@ -0,0 +1,93 @@
+//
+// Filename : AppStyleWindow.h
+// Author : Stephane Grabli
+// Purpose : Class to define the style window
+// Date of creation : 18/12/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 ARTSTYLEWINDOW_H
+#define ARTSTYLEWINDOW_H
+
+#include <QKeyEvent>
+#include <QWidget>
+#include <QPainter>
+#include <QColorGroup>
+#include "ui_dir/ui_stylewindow4.h"
+
+using namespace Ui;
+
+class AppInteractiveShaderWindow;
+class AppStyleWindow : public QDialog, public StyleWindow
+{
+ Q_OBJECT
+public:
+ AppStyleWindow(QWidget* parent = 0, const char* name = 0, Qt::WFlags fl = 0);
+ virtual ~AppStyleWindow();
+
+ void ExposeInteractiveShader();
+ /*! sets all layers to visible */
+ //void resetLayers();
+
+ virtual int currentRow() const { return PlayList->currentRow(); }
+ virtual void setModified(unsigned row, bool mod);
+ virtual void resetModified(bool iMod = false);
+ virtual void setChecked(unsigned row, bool check);
+
+public slots:
+ virtual void Add();
+ virtual void Add(const char* iFileName, bool iDisp = true);
+ virtual void SaveList();
+ virtual void Remove();
+ virtual void Clear();
+ virtual void Up();
+ virtual void Down();
+ virtual void Edit();
+ virtual void Close() { close(); }
+ virtual void Display( int row, int col);
+ virtual void ToggleLayer(int row, int col);
+ virtual void SwapShaders(int i1, int i2);
+ void fileSave();
+
+ protected:
+
+ void keyPressEvent(QKeyEvent *e) {
+ if (e->key() == Qt::Key_Escape)
+ return;
+ QDialog::keyPressEvent(e);
+ }
+
+private:
+
+ void AddList(const char* iFileName);
+
+ AppInteractiveShaderWindow* _pInteractiveShaderWindow;
+
+ QPixmap* _mod0_image;
+ QPixmap* _mod1_image;
+ QPixmap* _disp0_image;
+ QPixmap* _disp1_image;
+};
+
+#endif // ARTSTYLEWINDOW_H
diff --git a/source/blender/freestyle/intern/app/ConfigIO.cpp b/source/blender/freestyle/intern/app/ConfigIO.cpp
new file mode 100755
index 00000000000..8165deb07fd
--- /dev/null
+++ b/source/blender/freestyle/intern/app/ConfigIO.cpp
@@ -0,0 +1,116 @@
+
+//
+// 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 <qfileinfo.h>
+#include <qdir.h>
+#include "ConfigIO.h"
+
+ConfigIO::ConfigIO(QString filename, const QString& doc_type, bool automatic, const QString& sep)
+ : _default_file(filename), _automatic(automatic) {
+ _doc_type = doc_type;
+ _path_sep = sep;
+ if (_automatic)
+ loadFile();
+}
+
+ConfigIO::~ConfigIO() {
+ if (_automatic)
+ saveFile();
+}
+
+QString ConfigIO::getDefaultFile() const {
+ return _default_file;
+}
+
+void ConfigIO::setDefaultFile(const QString& filename) {
+ _default_file = filename;
+}
+
+bool ConfigIO::getAuto() const {
+ return _automatic;
+}
+
+void ConfigIO::setAuto(bool automatic) {
+ _automatic = automatic;
+}
+
+QString ConfigIO::getPathSep() const {
+ return _path_sep;
+}
+
+void ConfigIO::setPathSep(const QString& sep) {
+ _path_sep = sep;
+}
+
+int ConfigIO::loadFile(const QString& _filename) {
+
+ const QString filename = _filename.isEmpty() ? _default_file : _filename;
+
+ // check wether filename is a valid file and is readable
+ QFileInfo fileinfo(filename);
+ if (!fileinfo.isFile() || !fileinfo.isReadable()) {
+ std::cerr << "Warning: unable to load configuration file \""
+ << fileinfo.fileName().toAscii().data() << "\"" << std::endl;
+ return 1;
+ }
+
+ // read the DOM tree from file
+ QFile file(filename);
+ file.open(QIODevice::ReadOnly);
+ _tree.setContent(&file);
+ file.close();
+
+ return 0;
+}
+
+int ConfigIO::saveFile(const QString& _filename) const {
+
+ QString str_tree = _tree.toString();
+ if (str_tree.isEmpty())
+ return 1;
+
+ const QString filename = _filename.isEmpty() ? _default_file : _filename;
+
+ // if the directory in which we want to generate a file
+ // does not exist yet, try to create it
+ QFileInfo fileinfo(filename);
+ if (!fileinfo.exists()) {
+ QDir dir;
+ dir.mkdir(fileinfo.dir().path());
+ }
+
+ // check wether filename is a valid file and is writable
+ QFile file(filename);
+ file.open(QIODevice::WriteOnly);
+ if (!file.isOpen()) {
+ std::cerr << "Warning: unable to save configuration file \""
+ << fileinfo.fileName().toAscii().data() << "\"" << std::endl;
+ return 1;
+ }
+
+ // write the DOM tree to file
+ QTextStream out(&file);
+ out << str_tree;
+ file.close();
+
+ return 0;
+}
diff --git a/source/blender/freestyle/intern/app/ConfigIO.h b/source/blender/freestyle/intern/app/ConfigIO.h
new file mode 100755
index 00000000000..15f3cd07575
--- /dev/null
+++ b/source/blender/freestyle/intern/app/ConfigIO.h
@@ -0,0 +1,181 @@
+//
+// Filename : ConfigIO.h
+// Author(s) : Emmanuel Turquin
+// Purpose : Configuration management
+// 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 CONFIGIO_H
+# define CONFIGIO_H
+
+# include <qstring.h>
+# include <qstringlist.h>
+# include <qtextstream.h>
+# include <qdom.h>
+# include "../system/FreestyleConfig.h"
+
+class ConfigIO
+{
+ public:
+
+ ConfigIO(QString filename = "",
+ const QString& doc_type = "config_file",
+ bool automatic = false,
+ const QString& sep = "/");
+ ~ConfigIO();
+
+ QString getDefaultFile() const;
+ void setDefaultFile(const QString& filename);
+
+ bool getAuto() const;
+ void setAuto(bool automatic);
+
+ QString getPathSep() const;
+ void setPathSep(const QString& sep);
+
+ int loadFile(const QString& filename = "");
+ int saveFile(const QString& filename = "") const;
+
+ template <class T> int getValue(const QString& path, T& res) const;
+ template <class T> int setValue(const QString& path, const T& src);
+
+ private:
+
+ QString _path_sep;
+ QString _default_file;
+ bool _automatic;
+
+ QDomDocument _tree;
+ QString _doc_type;
+};
+
+
+//
+// Implementation of templated methods
+//
+///////////////////////////////////////////////////
+
+namespace Internal {
+
+ template <class T>
+ struct readValue {
+ void operator()(const QString &value, T &res) {
+ QTextStream((QString *)&value, QIODevice::ReadOnly)>> res;
+ }
+ };
+
+ template <>
+ struct readValue<QString> {
+ void operator()(const QString& value, QString& res) {
+ res = value;
+ }
+ };
+
+ template <>
+ struct readValue<bool> {
+ void operator()(const QString& value, bool& res) {
+ short res_tmp;
+ QTextStream((QString *)&value, QIODevice::ReadOnly) >> res_tmp;
+ res = res_tmp;
+ }
+ };
+
+} // end of namespace Internal
+
+
+template <class T>
+int ConfigIO::getValue(const QString& path, T& res) const {
+
+ // Split path
+ QStringList strlist;
+ strlist = path.split(_path_sep);
+
+ unsigned size = strlist.size();
+ if (size-- < 2)
+ return 1;
+
+ // try to find the right element
+ QDomElement right_node;
+ QDomElement node = _tree.documentElement().firstChild().toElement();
+ for (unsigned i = 0;
+ !node.isNull() && i < size;
+ node = node.firstChild().toElement(), i++) {
+ while (!node.isNull() && node.tagName() != strlist[i])
+ node = node.nextSibling().toElement();
+ right_node = node;
+ }
+
+ // and the right attribute
+ if (right_node.hasAttribute(strlist[size])) {
+ QString value = right_node.attribute(strlist[size]);
+ Internal::readValue<T> rv;
+ rv(value, res);
+ return 0;
+ }
+
+ return 1;
+}
+
+
+template <class T>
+int ConfigIO::setValue(const QString& path, const T& src) {
+
+ // Split path
+ QStringList strlist = path.split(_path_sep);
+
+ unsigned size = strlist.size();
+ if (size-- < 2)
+ return 1;
+
+ // verify that the tree isn't empty
+ // if so, create a root
+ QDomElement node = _tree.documentElement();
+ if (node.isNull()) {
+ node = _tree.createElement(_doc_type);
+ _tree.appendChild(node);
+ }
+
+ // find the right element
+ QDomElement child = node.firstChild().toElement();
+ for (unsigned i = 0;
+ i < size;
+ node = child, child = child.firstChild().toElement(), i++) {
+ while (!child.isNull() && child.tagName() != strlist[i])
+ child = child.nextSibling().toElement();
+ if (child.isNull()) {
+ child = _tree.createElement(strlist[i]);
+ node.appendChild(child);
+ }
+ }
+
+ // and set the attribute
+ QString value;
+ QTextStream(&value, QIODevice::WriteOnly) << src;
+ node.setAttribute(strlist[size], value);
+
+ return 0;
+}
+
+#endif // CONFIGIO_H
diff --git a/source/blender/freestyle/intern/app/Controller.cpp b/source/blender/freestyle/intern/app/Controller.cpp
new file mode 100755
index 00000000000..ac41b31ac78
--- /dev/null
+++ b/source/blender/freestyle/intern/app/Controller.cpp
@@ -0,0 +1,1498 @@
+
+//
+// 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 <fstream>
+#include <float.h>
+#include <qfileinfo.h>
+#include <qprocess.h>
+#include <qstring.h>
+
+#include "AppGLWidget.h"
+#include "AppMainWindow.h"
+#include "AppProgressBar.h"
+#include "AppStyleWindow.h"
+#include "AppOptionsWindow.h"
+#include "AppAboutWindow.h"
+#include "AppCanvas.h"
+#include "AppConfig.h"
+#include "AppDensityCurvesWindow.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
+
+Controller::Controller()
+{
+ const QString sep(Config::DIR_SEP.c_str());
+ const QString 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;
+
+ _pMainWindow = NULL;
+ _pView = NULL;
+
+ _edgeTesselationNature = (Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE);
+
+ _ProgressBar = new AppProgressBar;
+ _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(NULL != _VisibleProjectedSilhouette)
+ // {
+ // int ref = _VisibleProjectedSilhouette->destroy();
+ // if(0 == ref)
+ // delete _VisibleProjectedSilhouette;
+ // }
+
+ // if(NULL != _ProjectedSilhouette)
+ // {
+ // int ref = _ProjectedSilhouette->destroy();
+ // if(0 == ref)
+ // delete _ProjectedSilhouette;
+ // }
+
+ if(NULL != _ProgressBar)
+ {
+ delete _ProgressBar;
+ _ProgressBar = NULL;
+ }
+
+ 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;
+ }
+
+ // if(_pDensityCurvesWindow){
+ // delete _pDensityCurvesWindow;
+ // _pDensityCurvesWindow = 0;
+ // }
+ delete _current_dirs;
+}
+
+void Controller::SetView(AppGLWidget *iView)
+{
+ if(NULL == iView)
+ return;
+
+ _pView = iView;
+ //_pView2D->setGeometry(_pView->rect());
+ _Canvas->SetViewer(_pView);
+}
+
+void Controller::SetMainWindow(AppMainWindow *iMainWindow)
+{
+ _pMainWindow = iMainWindow;
+ _ProgressBar->setQTProgressBar(_pMainWindow->qtProgressDialog());
+ _pStyleWindow = new AppStyleWindow(_pMainWindow, "StyleWindow");
+ _pOptionsWindow = new AppOptionsWindow(_pMainWindow, "MainWindow");
+ _pDensityCurvesWindow = new AppDensityCurvesWindow(_pMainWindow, "MainWindow");
+}
+
+int Controller::Load3DSFile(const char *iFileName)
+{
+ if (_pView)
+ _pView->setUpdateMode(false);
+
+ //_pMainWindow->InitProgressBar("Loading 3DS Model", 4);
+ _ProgressBar->reset();
+ _ProgressBar->setLabelText("Loading 3DS Model");
+ _ProgressBar->setTotalSteps(3);
+ _ProgressBar->setProgress(0);
+
+ //_pMainWindow->setProgressLabel("Reading File");
+ //_pMainWindow->setProgressLabel("Cleaning mesh");
+
+ _pMainWindow->DisplayMessage("Reading File");
+ _pMainWindow->DisplayMessage("Cleaning Mesh");
+
+ MaxFileLoader loader3DS(iFileName);
+ //_RootNode->AddChild(BuildSceneTest());
+
+ _Chrono.start();
+
+ NodeGroup *maxScene = loader3DS.Load();
+
+ if (maxScene == NULL) {
+ _ProgressBar->setProgress(3);
+ 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;
+
+ _ProgressBar->setProgress(1);
+
+ // 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();
+
+ _pMainWindow->DisplayMessage("Building Winged Edge structure");
+ _Chrono.start();
+
+
+ WXEdgeBuilder wx_builder;
+ maxScene->accept(wx_builder);
+ _winged_edge = wx_builder.getWingedEdge();
+
+ printf("WEdge building : %lf\n", _Chrono.stop());
+
+ _ProgressBar->setProgress(2);
+
+ _pMainWindow->DisplayMessage("Building Grid");
+ _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();
+
+ _ProgressBar->setProgress(3);
+
+ _pView->SetDebug(_DebugNode);
+
+ //delete stuff
+ // if(0 != ws_builder)
+ // {
+ // delete ws_builder;
+ // ws_builder = 0;
+ // }
+ _pView->updateGL();
+ QFileInfo qfi(iFileName);
+ string basename((const char*)qfi.fileName().toAscii().data());
+ _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()) {
+ _pMainWindow->DisplayMessage("Error: Cannot save this file");
+ 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.toAscii().data() << endl << Config::VIEWMAP_VERSION.toAscii().data() << 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, _ProgressBar)) {
+ _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()) {
+ _pMainWindow->DisplayMessage("Error: Cannot load this file");
+ 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];
+ QString test;
+
+ ifs.getline(tmp_buffer, 255);
+ test = tmp_buffer;
+ if (test != Config::VIEWMAP_MAGIC) {
+ _pMainWindow->DisplayMessage(
+ (QString("Error: This is not a valid .") + Config::VIEWMAP_EXTENSION + QString(" file")).toAscii().data());
+ cerr << "Error: This is not a valid ." << Config::VIEWMAP_EXTENSION.toAscii().data() << " file" << endl;
+ return;
+ }
+ ifs.getline(tmp_buffer, 255);
+ test = tmp_buffer;
+ if (test != Config::VIEWMAP_VERSION && !only_camera) {
+ _pMainWindow->DisplayMessage(
+ (QString("Error: This version of the .") + Config::VIEWMAP_EXTENSION + QString(" file format is no longer supported")).toAscii().data());
+ cerr << "Error: This version of the ." << Config::VIEWMAP_EXTENSION.toAscii().data() << " 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) {
+ _pMainWindow->DisplayMessage("Error: cannot find the right model(s)");
+ 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) {
+ _pMainWindow->DisplayMessage("Camera parameters loaded");
+ 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, _ProgressBar)) {
+ _Chrono.stop();
+ _pMainWindow->DisplayMessage(
+ (QString("Error: This is not a valid .") + Config::VIEWMAP_EXTENSION + QString(" file")).toAscii().data());
+ cerr << "Error: This is not a valid ." << Config::VIEWMAP_EXTENSION.toAscii().data() << " file" << endl;
+ return;
+ }
+
+ // Update display
+ _pMainWindow->DisplayMessage("Updating 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];
+ _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();
+ if (_SceneNumFaces > 2000)
+ edgeDetector.SetProgressBar(_ProgressBar);
+
+ 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);
+
+ // FIXME GLDEBUG
+ //====================================================================
+ // NodeShape * silhouetteDebugShape = new NodeShape;
+ // _DebugNode->AddChild(silhouetteDebugShape);
+ // vector<WShape*>& wshapes = _winged_edge->getWShapes();
+ // vector<WShape*>::iterator ws, wsend;
+ // for(ws=wshapes.begin(), wsend=wshapes.end();
+ // ws!=wsend;
+ // ++ws){
+ // smooth
+// vector<WVertex*>& wvertices = (*ws)->GetVertexList();
+// unsigned modulo(1), currentIndex(0);
+// for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end();
+// wv!=wvend;
+// ++wv){
+// if(currentIndex%modulo != 0){
+// ++currentIndex;
+// continue;
+// }else
+// ++currentIndex;
+
+// WVertex::face_iterator fit=(*wv)->faces_begin();
+// WVertex::face_iterator fitend=(*wv)->faces_end();
+// for(; fit!=fitend; ++fit){
+// WXFace *wxf = dynamic_cast<WXFace*>(*fit);
+// unsigned vindex = wxf->GetIndex((*wv));
+// vector<WXFaceLayer*> flayers;
+// wxf->retrieveSmoothLayers(Nature::RIDGE, flayers);
+// for(vector<WXFaceLayer*>::iterator fl=flayers.begin(), flend=flayers.end();
+// fl!=flend;
+// ++fl){
+// Vec3r c[3];
+// unsigned index = 0;
+// for(unsigned i=0; i<3; ++i){
+// // real d = (*fl)->dotP(i);
+// real d = ((WXVertex*)(wxf->GetVertex(i)))->curvatures()->Kr;
+// if(d < 0){
+// index = 1;
+// d = -d;
+// }
+// else
+// index = 0;
+// c[i][index] = d;
+// }
+// TriangleRep * frep = new TriangleRep( wxf->GetVertex(0)->GetVertex(),
+// c[0],
+// wxf->GetVertex(1)->GetVertex(),
+// c[1],
+// wxf->GetVertex(2)->GetVertex(),
+// c[2]);
+// silhouetteDebugShape->AddRep(frep);
+ //
+ // //
+ // Vec3r e2 = ((Face_Curvature_Info*)(*fl)->userdata)->vec_curvature_info[vindex]->e2;
+ // Vec3r e1 = ((Face_Curvature_Info*)(*fl)->userdata)->vec_curvature_info[vindex]->e1;
+ // OrientedLineRep * olrep1 = new OrientedLineRep((*wv)->GetVertex(), (*wv)->GetVertex()+e1);
+ // OrientedLineRep * olrep2 = new OrientedLineRep((*wv)->GetVertex(), (*wv)->GetVertex()+e2);
+ // silhouetteDebugShape->AddRep(olrep1);
+ // silhouetteDebugShape->AddRep(olrep2);
+ // WOEdge * oppositeEdge;
+ // if(!(wxf->getOppositeEdge(*wv, oppositeEdge)))
+ // continue;
+ // Vec3r v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex();
+ // OrientedLineRep * opplrep = new OrientedLineRep(oppositeEdge->GetaVertex()->GetVertex(), oppositeEdge->GetaVertex()->GetVertex()+v1v2);
+ // silhouetteDebugShape->AddRep(opplrep);
+ // GeomUtils::intersection_test res;
+ // real t;
+ // res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2,
+ // e2, -((*wv)->GetVertex()*e2),
+ // t,1.e-06);
+ // if((res == GeomUtils::DO_INTERSECT) && (t>=0.0) && (t<=1.0)){
+ // Vec3r inter(oppositeEdge->GetaVertex()->GetVertex() + t*v1v2);
+ // VertexRep * irep = new VertexRep(inter.x(), inter.y(), inter.z());
+ // irep->SetPointSize(5.0);
+ // silhouetteDebugShape->AddRep(irep);
+ // }
+// }
+// }
+// //break;
+// }
+
+ // vector<WFace*>& wfaces = (*ws)->GetFaceList();
+ // for(vector<WFace*>::iterator wf=wfaces.begin(), wfend=wfaces.end();
+ // wf!=wfend;
+ // ++wf){
+ // WXFace *wxf = dynamic_cast<WXFace*>(*wf);
+ // vector<WXSmoothEdge*> smoothEdges;
+ // wxf->retrieveSmoothEdges(Nature::RIDGE, smoothEdges);
+ // for(vector<WXSmoothEdge*>::iterator se=smoothEdges.begin(), send=smoothEdges.end();
+ // se!=send;
+ // ++se){
+ // real ta = (*se)->ta();
+ // Vec3r A1((*se)->woea()->GetaVertex()->GetVertex());
+ // Vec3r A2((*se)->woea()->GetbVertex()->GetVertex());
+ // Vec3r A(A1+ta*(A2-A1));
+ //
+ // real tb = (*se)->tb();
+ // Vec3r B1((*se)->woeb()->GetaVertex()->GetVertex());
+ // Vec3r B2((*se)->woeb()->GetbVertex()->GetVertex());
+// Vec3r B(B1+tb*(B2-B1));
+// OrientedLineRep * line = new OrientedLineRep(A,B);
+// silhouetteDebugShape->AddRep(line);
+// }
+// Material redmat;
+// redmat.SetDiffuse(1,0,0,1);
+// Material greenmat;
+// greenmat.SetDiffuse(0,1,0,1);
+// real vecSize = _bboxDiag/70.0;
+// vector<WXFaceLayer*> flayers;
+// wxf->retrieveSmoothLayers(Nature::RIDGE, flayers);
+// for(vector<WXFaceLayer*>::iterator fl=flayers.begin(), flend=flayers.end();
+// fl!=flend;
+// ++fl){
+ // Vec3r c[3];
+ // unsigned nNegative = 0;
+ // unsigned index = 0;
+ // for(unsigned i=0; i<3; ++i){
+ // //real d = (*fl)->dotP(i);
+ // real d = ((Face_Curvature_Info*)(*fl)->userdata)->vec_curvature_info[i]->K1/50.0;
+ // //cout << d << endl;
+ // if(d < 0){
+ // nNegative++;
+ // index = 1;
+ // d = -d;
+ // }
+ // else
+ // index = 0;
+ // c[i][index] = d;
+ // }
+ // TriangleRep * frep = new TriangleRep( wxf->GetVertex(0)->GetVertex(),
+ // c[0],
+ // wxf->GetVertex(1)->GetVertex(),
+ // c[1],
+ // wxf->GetVertex(2)->GetVertex(),
+ // c[2]);
+ // //if((nNegative != 0) && (nNegative != 3))
+ // silhouetteDebugShape->AddRep(frep);
+
+ // 3D CURVATURES
+ //==============
+ // Face_Curvature_Info * fci = (Face_Curvature_Info*)(*fl)->userdata;
+ // unsigned nvertices = wxf->numberOfVertices();
+ // for(i=0; i<nvertices; ++i){
+ // Curvature_info * ci = fci->vec_curvature_info[i];
+ // Vec3r v(wxf->GetVertex(i)->GetVertex());
+ // // VertexRep *vrep = new VertexRep(v[0], v[1], v[2]);
+ // // vrep->SetMaterial(redmat);
+ // // vrep->SetPointSize(5.0);
+ // // silhouetteDebugShape->AddRep(vrep);
+ // // LineRep * maxc = new LineRep(v-vecSize*ci->e1/2.0, v+vecSize*ci->e1/2.0);
+ // // LineRep * maxc = new LineRep(v, v+vecSize*ci->e1);
+ // // maxc->SetMaterial(redmat);
+ // // maxc->SetWidth(2.0);
+ // // silhouetteDebugShape->AddRep(maxc);
+ // LineRep * minc = new LineRep(v, v+vecSize*ci->e2);
+ // minc->SetMaterial(greenmat);
+ // minc->SetWidth(2.0);
+ // silhouetteDebugShape->AddRep(minc);
+ // }
+// }
+// }
+// }
+
+ //
+ // // Sharp
+ // vector<WEdge*>& wedges = (*ws)->GetEdgeList();
+ // for(vector<WEdge*>::iterator we=wedges.begin(), weend=wedges.end();
+ // we!=weend;
+ // ++we){
+ // WXEdge * wxe = dynamic_cast<WXEdge*>(*we);
+ // if((wxe)->nature() != Nature::NO_FEATURE){
+ // OrientedLineRep * line = new OrientedLineRep( wxe->GetaVertex()->GetVertex(),
+ // wxe->GetbVertex()->GetVertex());
+ // silhouetteDebugShape->AddRep(line);
+ // }
+ // }
+ // }
+ // WVertex *wvertex = _winged_edge->getWShapes()[0]->GetVertexList()[0];
+ // Vec3r v(wvertex->GetVertex());
+ // VertexRep * vrep = new VertexRep(v[0],v[1], v[2]);
+ // silhouetteDebugShape->AddRep(vrep );
+ // WVertex::face_iterator fit = wvertex->faces_begin();
+ // WVertex::face_iterator fitend = wvertex->faces_end();
+ // while(fit!=fitend){
+ // vector<WVertex*> fvertices;
+ // (*fit)->RetrieveVertexList(fvertices);
+ // Vec3r v[3];
+ // unsigned i=0;
+ // for(vector<WVertex*>::iterator fv=fvertices.begin(), fvend=fvertices.end();
+ // fv!=fvend;
+ // ++fv, ++i){
+ // v[i] = (*fv)->GetVertex();
+ // }
+ // TriangleRep * triangle = new TriangleRep(v[0], v[1], v[2]);
+ // silhouetteDebugShape->AddRep(triangle);
+ // ++fit;
+ // }
+ //====================================================================
+ // END GLDEBUG
+
+ // Builds the view map structure from the flagged WSEdge structure:
+ //----------------------------------------------------------
+ ViewMapBuilder vmBuilder;
+ vmBuilder.SetProgressBar(_ProgressBar);
+ 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);
+
+ // FIXME DEBUG
+ // vector<ViewVertex*>& vvertices = _ViewMap->ViewVertices();
+ // for(vector<ViewVertex*>::iterator vv=vvertices.begin(), vvend=vvertices.end();
+ // vv!=vvend;
+ // ++vv){
+ // TVertex * tvertex = (*vv)->castToTVertex();
+ // if(!tvertex)
+ // continue;
+ // cout << "TVertex : " << tvertex->getId() << endl;
+ // if (!(tvertex->frontEdgeA().first))
+ // cout << "null FrontEdgeA" << endl;
+ // if (!(tvertex->frontEdgeB().first))
+ // cout << "null FrontEdgeB" << endl;
+ // if (!(tvertex->backEdgeA().first))
+ // cout << "null BackEdgeA" << endl;
+ // if (!(tvertex->backEdgeB().first))
+ // cout << "null backEdgeB" << endl;
+ // }
+ // cout << "-----------" << endl;
+ // vector<SVertex*>& svertices = _ViewMap->SVertices();
+ // unsigned i = 0;
+ // for(vector<SVertex*>::iterator sv = svertices.begin(), svend = svertices.end();
+ // sv != svend && i < 10;
+ // ++sv, ++i) {
+ // cout << "SVertex - Id : " << (*sv)->getId() << endl;
+ // cout << "SVertex - P3D : " << (*sv)->point3D() << endl;
+ // cout << "SVertex - P2D : " << (*sv)->point2D() << endl;
+ // set<Vec3r>::const_iterator i;
+ // unsigned tmp;
+ // for (i = (*sv)->normals().begin(), tmp = 0;
+ // i != (*sv)->normals().end();
+ // i++, tmp++);
+ // cout << "SVertex - Normals : " << tmp << endl;
+ // cout << "SVertex - FEdges : " << (*sv)->fedges().size() << endl;
+ // }
+ // cout << "-----------" << endl;
+ // vector<FEdge*>& fedges = _ViewMap->FEdges();
+ // for(vector<FEdge*>::iterator fe = fedges.begin(), feend = fedges.end();
+ // fe != feend && i < 10;
+ // ++fe, ++i) {
+ // cout << "FEdge - Id: " << (*fe)->getId() << endl;
+ // cout << "FEdge - Occl: " << (*fe)->getOccludeeIntersection() << endl;
+ // }
+ // cout << "-----------" << endl;
+ // END DEBUG
+
+ // FIXME GLDEBUG
+ //====================================================================
+ // CUSPS
+ //=======
+ // vector<ViewEdge*>& vedges = _ViewMap->ViewEdges();
+ // //typedef ViewEdgeInternal::fedge_iterator_base<Nonconst_traits<FEdge*> > fedge_iterator;
+ // //fedge_iterator fit = vedges[0]->fedge_iterator_begin();
+ // for(vector<ViewEdge*>::iterator ve=vedges.begin(), veend=vedges.end();
+ // ve!=veend;
+ // ++ve){
+ // if((!((*ve)->getNature() & Nature::SILHOUETTE)) || (!((*ve)->fedgeA()->isSmooth())))
+ // continue;
+ // FEdge *fe = (*ve)->fedgeA();
+ // FEdge * fefirst = fe;
+ // //ViewEdge::fedge_iterator fit = (*ve)->fedge_iterator_begin();
+ // //ViewEdge::vertex_iterator vit = (*ve)->vertices_begin();
+ //
+ // Material mat;
+ // // for(; !(fe.end()); ++fe){
+ // bool first = true;
+ // bool front = true;
+ // bool positive = true;
+ // do{
+ // FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
+ // Vec3r A((fes)->vertexA()->point3d());
+ // Vec3r B((fes)->vertexB()->point3d());
+ // Vec3r AB(B-A);
+ // AB.normalize();
+ // LineRep * lrep = new LineRep(A,B);
+ // silhouetteDebugShape->AddRep(lrep);
+ // Vec3r m((A+B)/2.0);
+ // Vec3r crossP(AB^(fes)->normal());
+ // crossP.normalize();
+ // Vec3r viewvector(m-vp);
+ // viewvector.normalize();
+ // if(first){
+ // if(((crossP)*(viewvector)) > 0)
+ // positive = true;
+ // else
+ // positive = false;
+ // first = false;
+ // }
+ // if(positive){
+ // if(((crossP)*(viewvector)) < -0.2)
+ // positive = false;
+ // }else{
+ // if(((crossP)*(viewvector)) > 0.2)
+ // positive = true;
+ // }
+ // if(positive)
+ // mat.SetDiffuse(1,1,0,1);
+ // else
+ // mat.SetDiffuse(1,0,0,1);
+ // lrep->SetMaterial(mat);
+ // fe = fe->nextEdge();
+ // }while((fe!=0) && (fe!=fefirst));
+ // }
+ //====================================================================
+ // END FIXME GLDEBUG
+
+ _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(){
+ if((!_Canvas) || (!_ViewMap))
+ return;
+
+ if(_ProgressBar){
+ _ProgressBar->reset();
+ _ProgressBar->setLabelText("Computing Steerable ViewMap");
+ _ProgressBar->setTotalSteps(3);
+ _ProgressBar->setProgress(0);
+ }
+
+ // 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();
+
+ _pMainWindow->DisplayMessage("Dividing up edges");
+ 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);
+ }
+ }
+ if(_ProgressBar)
+ _ProgressBar->setProgress(1);
+ _pMainWindow->DisplayMessage("Rendering Steerable ViewMap");
+ 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");
+ }
+ //#else
+// // LINUX
+// QGLBasicWidget offscreenBuffer(_pView, "SteerableViewMap", _pView->width(), _pView->height());
+
+// float * buffer = 0;
+// for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){
+// offscreenBuffer.AddNode(ng[i]);
+// offscreenBuffer.draw();
+// img[i] = new GrayImage(_pView->width(), _pView->height());
+// buffer = img[i]->getArray();
+// offscreenBuffer.readPixels(0,0,_pView->width(), _pView->height(), buffer);
+// for(unsigned y=0;y<img[i]->height();++y){
+// for(unsigned x=0;x<img[i]->width();++x){
+// img[i]->setPixel(x,y,255.f *img[i]->pixel(x,y));
+// }
+// }
+
+// offscreenBuffer.DetachNode(ng[i]);
+// ng[i]->destroy();
+// delete ng[i];
+// }
+// #endif
+ if(_ProgressBar)
+ _ProgressBar->setProgress(2);
+ _pMainWindow->DisplayMessage("Building Gaussian Pyramids");
+ svm->buildImagesPyramids(img,false,0,1.f);
+ if(_ProgressBar)
+ _ProgressBar->setProgress(3);
+}
+
+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;
+ _pMainWindow->DisplayMessage("Visibility algorithm switched to \"fast ray casting\"");
+ }
+ else if (_VisibilityAlgo == ViewMapBuilder::ray_casting_fast) {
+ _VisibilityAlgo = ViewMapBuilder::ray_casting_very_fast;
+ _pMainWindow->DisplayMessage("Visibility algorithm switched to \"very fast ray casting\"");
+ }
+ else {
+ _VisibilityAlgo = ViewMapBuilder::ray_casting;
+ _pMainWindow->DisplayMessage("Visibility algorithm switched to \"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);
+ QString ext = fi.suffix();
+ if (ext != "py") {
+ cerr << "Error: Cannot load \"" << fi.fileName().toAscii().data()
+ << "\", 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::ExposeStyleWindow()
+{
+ _pStyleWindow->show();
+}
+
+void Controller::ExposeOptionsWindow()
+{
+ _pOptionsWindow->show();
+}
+
+void Controller::ExposeHelpWindow()
+{
+ QStringList cmd_list = _browser_cmd.split(" ");
+ for (QStringList::iterator it = cmd_list.begin();
+ it != cmd_list.end();
+ ++it)
+ (*it).replace("%s", _help_index);
+ QProcess browser(0);
+ QString exe = cmd_list.first();
+ cmd_list.removeFirst();
+ browser.start(exe, cmd_list);
+}
+
+void Controller::ExposeAboutWindow()
+{
+ AppAboutWindow::display();
+}
+
+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::savePSSnapshot(const QString& iFileName){
+ PSStrokeRenderer psRenderer((const char*)iFileName.toAscii().data());
+ _Canvas->Render(&psRenderer);
+ psRenderer.Close();
+}
+
+void Controller::saveTextSnapshot(const QString& iFileName){
+ TextStrokeRenderer textRenderer((const char*)iFileName.toAscii().data());
+ _Canvas->Render(&textRenderer);
+ textRenderer.Close();
+}
+
+void Controller::captureMovie() {
+ _pView->captureMovie();
+}
+
+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 QString& dir) {
+ _current_dirs->setValue("models/dir", dir);
+}
+
+QString Controller::getModelsDir() const {
+ QString dir = ".";
+ _current_dirs->getValue("models/dir", dir);
+ return dir;
+}
+
+void Controller::setModulesDir(const QString& dir) {
+ _current_dirs->setValue("modules/dir", dir);
+}
+
+QString Controller::getModulesDir() const {
+ QString dir = ".";
+ _current_dirs->getValue("modules/dir", dir);
+ return dir;
+}
+
+void Controller::setPapersDir(const QString& dir) {
+ _current_dirs->setValue("papers/dir", dir);
+}
+
+QString Controller::getPapersDir() const {
+ QString dir = Config::Path::getInstance()->getPapersDir();
+ _current_dirs->getValue("papers/dir", dir);
+ return dir;
+}
+
+void Controller::setHelpIndex(const QString& index) {
+ _help_index = index;
+}
+
+QString Controller::getHelpIndex() const {
+ return _help_index;
+}
+
+void Controller::setBrowserCmd(const QString& cmd) {
+ _browser_cmd = cmd;
+}
+
+QString Controller::getBrowserCmd() const {
+ return _browser_cmd;
+}
+
+void Controller::resetInterpreter() {
+ if (_inter)
+ _inter->reset();
+}
+
+void Controller::displayMessage(const char * msg, bool persistent){
+ _pMainWindow->DisplayMessage(msg, persistent);
+}
+
+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/Controller.h b/source/blender/freestyle/intern/app/Controller.h
new file mode 100755
index 00000000000..95b97ebcda3
--- /dev/null
+++ b/source/blender/freestyle/intern/app/Controller.h
@@ -0,0 +1,232 @@
+//
+// 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 AppProgressBar;
+class AppGLWidget;
+class AppMainWindow;
+class NodeGroup;
+class WShape;
+class SShape;
+class ViewMap;
+class ViewEdge;
+class AppCanvas;
+class InteractiveShader;
+class Shader;
+class AppInteractiveShaderWindow;
+class AppStyleWindow;
+class AppOptionsWindow;
+class AppDensityCurvesWindow;
+
+class Controller
+{
+public:
+ Controller() ;
+ ~Controller() ;
+
+ void SetView(AppGLWidget *iView);
+ void SetMainWindow(AppMainWindow *iMainWindow);
+ 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 ExposeStyleWindow();
+ void ExposeOptionsWindow();
+ void ExposeHelpWindow();
+ void ExposeAboutWindow();
+ 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 savePSSnapshot(const QString& iFileName);
+ void saveTextSnapshot(const QString& iFileName);
+ void captureMovie();
+ void displayMessage(const char *msg, bool persistent = 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;}
+
+ AppProgressBar* getProgressBar(void) { return _ProgressBar; }
+
+ void setModelsDir(const QString& dir);
+ QString getModelsDir() const;
+ void setModulesDir(const QString& dir);
+ QString getModulesDir() const;
+ void setPapersDir(const QString& dir);
+ QString getPapersDir() const;
+ void setHelpIndex(const QString& dir);
+ QString getHelpIndex() const;
+ void setBrowserCmd(const QString& cmd);
+ QString 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;
+
+ // Progress Bar
+ AppProgressBar *_ProgressBar;
+
+ // 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;
+
+ QString _help_index;
+ QString _browser_cmd;
+
+ bool _EnableQI;
+ bool _ComputeRidges;
+ bool _ComputeSuggestive;
+ real _sphereRadius;
+ real _suggestiveContourKrDerivativeEpsilon;
+
+ bool _ComputeSteerableViewMap;
+
+ FEdgeXDetector edgeDetector;
+};
+
+extern Controller *g_pController;
+
+#endif // CONTROLLER_H
diff --git a/source/blender/freestyle/intern/app/Main.cpp b/source/blender/freestyle/intern/app/Main.cpp
new file mode 100755
index 00000000000..ae4d28017c5
--- /dev/null
+++ b/source/blender/freestyle/intern/app/Main.cpp
@@ -0,0 +1,57 @@
+
+//
+// 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 <QApplication>
+#include <qgl.h>
+#include "Controller.h"
+#include "AppMainWindow.h"
+#include "AppConfig.h"
+
+// Global
+Controller *g_pController;
+
+int main(int argc, char** argv)
+{
+ // sets the paths
+ QApplication::setColorSpec(QApplication::ManyColor);
+ QApplication *app = new QApplication(argc, argv);
+ Q_INIT_RESOURCE(freestyle);
+
+ Config::Path pathconfig;
+
+ QGLFormat myformat;
+ myformat.setAlpha(true);
+ QGLFormat::setDefaultFormat( myformat );
+
+ AppMainWindow mainWindow(NULL, "Freestyle");
+ //app->setMainWidget(mainWindow); // QT3
+
+ g_pController = new Controller;
+ g_pController->SetMainWindow(&mainWindow);
+ g_pController->SetView(mainWindow.pQGLWidget);
+
+ mainWindow.show();
+
+ int res = app->exec();
+
+ delete g_pController;
+
+ return res;
+}
diff --git a/source/blender/freestyle/intern/app/QGLBasicWidget.cpp b/source/blender/freestyle/intern/app/QGLBasicWidget.cpp
new file mode 100755
index 00000000000..44b5e0de224
--- /dev/null
+++ b/source/blender/freestyle/intern/app/QGLBasicWidget.cpp
@@ -0,0 +1,141 @@
+
+//
+// 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 "QGLBasicWidget.h"
+#include "../rendering/GLRenderer.h"
+// #ifndef WIN32
+// #include "../rendering/pbuffer.h"
+// #endif
+
+QGLBasicWidget::QGLBasicWidget( QWidget* parent, const char* name, int w, int h, const QGLWidget* shareWidget )
+ : QGLWidget( parent, shareWidget )
+{
+ _pGLRenderer = new GLRenderer;
+// #ifndef WIN32
+// _Pbuffer = new PBuffer(w,h,
+// PBuffer::SingleBuffer
+// | PBuffer::DepthBuffer
+// | PBuffer::StencilBuffer);
+
+// _Pbuffer->create(false);
+// #endif
+ resizeGL(w,h);
+ _RootNode.SetLightingEnabled(false);
+ _RootNode.SetLineWidth(1.0);
+}
+
+QGLBasicWidget::QGLBasicWidget( const QGLFormat& format, QWidget* parent, const char* name,
+ int w, int h, const QGLWidget* shareWidget )
+ : QGLWidget( format, parent, shareWidget )
+{
+ _pGLRenderer = new GLRenderer;
+// #ifndef WIN32
+// _Pbuffer = new PBuffer(w,h,
+// PBuffer::SingleBuffer
+// | PBuffer::DepthBuffer
+// | PBuffer::StencilBuffer);
+// _Pbuffer->create(false);
+// #endif
+ resizeGL(w,h);
+ _RootNode.SetLightingEnabled(false);
+ _RootNode.SetLineWidth(1.0);
+}
+
+QGLBasicWidget::~QGLBasicWidget()
+{
+ _RootNode.destroy();
+ if(_pGLRenderer)
+ delete _pGLRenderer;
+// #ifndef WIN32
+// if(_Pbuffer)
+// delete _Pbuffer;
+// #endif
+}
+
+void QGLBasicWidget::AddNode(Node* iNode){
+ _RootNode.AddChild(iNode);
+}
+
+void QGLBasicWidget::DetachNode(Node* iNode){
+ _RootNode.DetachChild(iNode);
+}
+
+void QGLBasicWidget::readPixels(int x,
+ int y,
+ int width,
+ int height,
+ float *pixels){
+// #ifndef WIN32
+// _Pbuffer->makeCurrent();
+
+// glReadBuffer(GL_FRONT);
+// GLenum e = glGetError();
+// GLenum glformat = GL_RED;
+// glReadPixels(x,y,width, height, glformat, GL_FLOAT, (GLfloat*)pixels);
+// e = glGetError();
+// #endif
+}
+
+void QGLBasicWidget::initializeGL()
+{
+ glClearColor(_clearColor[0],_clearColor[1],_clearColor[2],1);
+}
+
+void QGLBasicWidget::resizeGL( int w, int h )
+{
+// #ifndef WIN32
+// _Pbuffer->makeCurrent();
+// #endif
+
+ glViewport( 0, 0, (GLint)w, (GLint)h );
+ // Projection Matrix
+ //==================
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+// #ifndef WIN32
+// // FXS- changed order of y bounds for glRead
+// glOrtho(0,w, h, 0, -1.0, 1.0);
+// #else
+ glOrtho(0,w, 0, h, -1.0, 1.0);
+ //#endif
+}
+
+void QGLBasicWidget::paintGL()
+{
+// #ifndef WIN32
+// _Pbuffer->makeCurrent();
+// glClearColor(_clearColor[0],_clearColor[1],_clearColor[2],1);
+// #endif
+
+ glDrawBuffer( GL_FRONT);
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ //Modelview Matrix
+ //================
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glDisable(GL_DEPTH_TEST);
+ _RootNode.accept(*_pGLRenderer);
+ glPopAttrib();
+}
+
diff --git a/source/blender/freestyle/intern/app/QGLBasicWidget.h b/source/blender/freestyle/intern/app/QGLBasicWidget.h
new file mode 100755
index 00000000000..9b29a641f28
--- /dev/null
+++ b/source/blender/freestyle/intern/app/QGLBasicWidget.h
@@ -0,0 +1,102 @@
+//
+// Filename : QGLBasicWidget.h
+// Author : Stephane Grabli
+// Purpose : A basic qgl widget designed to be used as
+// a 2D offscreen buffer. (no interactive function)
+// Date of creation : 26/12/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 QGLBASICWIDGET_H
+#define QGLBASICWIDGET_H
+
+#include <qgl.h>
+#include "../geometry/Geom.h"
+//#include "../rendering/pbuffer.h"
+#include "../scene_graph/NodeDrawingStyle.h"
+using namespace Geometry;
+
+class GLRenderer;
+class ViewMap;
+// #ifndef WIN32
+// class PBuffer;
+// #endif
+class QGLBasicWidget : public QGLWidget
+{
+ Q_OBJECT
+
+public:
+
+ QGLBasicWidget( QWidget* parent, const char* name, int w, int h, const QGLWidget* shareWidget=0 );
+ QGLBasicWidget( const QGLFormat& format, QWidget* parent, const char* name,
+ int w, int h, const QGLWidget* shareWidget=0 );
+ ~QGLBasicWidget();
+
+ /*! Adds a node directly under the root node */
+ void AddNode(Node* iNode);
+ /*! Detach the node iNode which must
+ * be directly under the root node.
+ */
+ void DetachNode(Node *iNode);
+
+ /*! reads the frame buffer pixels as luminance .
+ * \param x
+ * The lower-left corner x-coordinate of the
+ * rectangle we want to grab.
+ * \param y
+ * The lower-left corner y-coordinate of the
+ * rectangle we want to grab.
+ * \param width
+ * The width of the rectangle we want to grab.
+ * \param height
+ * The height of the rectangle we want to grab.
+ * \params pixels
+ * The array of float (of size width*height) in which
+ * the read values are stored.
+ */
+ void readPixels(int x,int y,int width,int height,float *pixels) ;
+// #ifndef WIN32
+// void draw() { paintGL(); }
+// #endif
+
+ inline void SetClearColor(const Vec3f& c) {_clearColor = c;}
+ inline Vec3f getClearColor() const {return _clearColor;}
+
+protected:
+
+ virtual void initializeGL();
+ virtual void paintGL();
+ virtual void resizeGL(int w, int h);
+
+private:
+// #ifndef WIN32
+// PBuffer *_Pbuffer;
+// #endif
+ NodeDrawingStyle _RootNode;
+ Vec3f _clearColor;
+ GLRenderer *_pGLRenderer;
+};
+
+
+#endif // QGLBASICWIDGET_H
diff --git a/source/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.cpp b/source/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.cpp
new file mode 100755
index 00000000000..16ea53f157c
--- /dev/null
+++ b/source/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.cpp
@@ -0,0 +1,155 @@
+
+//
+// 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 "QStyleModuleSyntaxHighlighter.h"
+#include <QTextEdit>
+#include <QRegExp>
+#include <iostream>
+using namespace std;
+
+QStyleModuleSyntaxHighlighter::QStyleModuleSyntaxHighlighter(QTextEdit *iTextEdit)
+ : QSyntaxHighlighter(iTextEdit){
+ _operators.push_back("Operators");
+ _operators.push_back("select");
+ _operators.push_back("chain");
+ _operators.push_back("bidirectionalChain");
+ _operators.push_back("sequentialSplit");
+ _operators.push_back("recursiveSplit");
+ _operators.push_back("sort");
+ _operators.push_back("create");
+
+ _functors.push_back("StrokeShader");
+ _functors.push_back("UnaryPredicate1D");
+ _functors.push_back("UnaryPredicate0D");
+ _functors.push_back("BinaryPredicate1D");
+ _functors.push_back("ChainingIterator");
+ // _functors.push_back("getName");
+ // _functors.push_back("shade");
+ // _functors.push_back("getObject");
+
+ _python.push_back("class ");
+ _python.push_back("from ");
+ _python.push_back("import ");
+ _python.push_back("__init__");
+ _python.push_back("__call__");
+ _python.push_back("def ");
+ _python.push_back("self");
+ _python.push_back("return");
+ //_python.push_back("print");
+ // _python.push_back("for");
+ // _python.push_back("if");
+ // _python.push_back("while");
+ // _python.push_back("range");
+ // _python.push_back("in");
+
+ _defaultColor = iTextEdit->textColor();
+}
+
+QStyleModuleSyntaxHighlighter::~QStyleModuleSyntaxHighlighter(){
+ _operators.clear();
+ _functors.clear();
+ _python.clear();
+}
+
+void QStyleModuleSyntaxHighlighter::highlightKeywords(const QString& text, vector<QString>& iKeywords, const QColor& iColor){
+ int pos = 0;
+ int pos1 = 0;
+ int pos2 = 0;
+ bool found = false;
+ for(vector<QString>::iterator o=iKeywords.begin(), oend=iKeywords.end();
+ o!=oend;
+ ++o){
+ pos =0;
+ QString word = *o;
+ while ( ( pos = text.indexOf(word,pos) ) != -1 ){
+ setFormat( pos , word.length() , iColor);
+ pos += text.length()+1;
+ }
+
+ // while ( ( pos = text.find(QRegExp("(^|\\W)"+word+"\\W"),pos) ) != -1 ){
+ // setFormat( pos , word.length()+1 , iColor);
+ // pos += text.length()+1;
+ // }
+ }
+}
+
+void QStyleModuleSyntaxHighlighter::dynamicHighlight(const QString& text){
+ int pos = 0;
+ int pos1 = 0;
+ int pos2 = 0;
+ while((pos1 = text.indexOf("class", pos, Qt::CaseSensitive) ) != -1 ){
+ int tmpPos = pos1+6;
+ if( ( pos2 = text.indexOf('(',tmpPos, Qt::CaseSensitive) ) != -1 ){
+ setFormat( tmpPos , pos2-tmpPos , QColor(0,0,255));
+ pos += pos2 - pos1+1;
+ } else{
+ setFormat( tmpPos, text.length()-tmpPos, QColor(0,0,255));
+ pos += text.length()+1;
+ }
+ }
+
+ while((pos1 = text.indexOf("def",pos, Qt::CaseSensitive) ) != -1 ){
+ int tmpPos = pos1+4;
+ if( ( pos2 = text.indexOf('(',tmpPos, Qt::CaseSensitive) ) != -1 ){
+ setFormat( tmpPos , pos2-tmpPos , QColor(136,0,0));
+ pos += pos2 - pos1+1;
+ } else{
+ setFormat( tmpPos, text.length()-tmpPos, QColor(136,0,0));
+ pos += text.length()+1;
+ }
+ }
+
+ pos = 0;
+ while((pos1 = text.indexOf("UnaryFunction", pos) ) != -1 ){
+ if( ( pos2 = text.indexOf(QRegExp("\\W"), pos1) ) != -1 ){
+ setFormat( pos1 , pos2-pos1 , QColor(0,0,255));
+ pos += pos2 - pos1+1;
+ } else{
+ setFormat( pos1, text.length()-pos1, QColor(0,0,255));
+ pos += text.length()+1;
+ }
+ }
+}
+
+void QStyleModuleSyntaxHighlighter::highlightComment(const QString& text){
+ int pos = 0;
+ int pos1 = 0;
+ int pos2 = 0;
+ while((pos1 = text.indexOf('#',pos, Qt::CaseSensitive) ) != -1 ){
+ if( ( pos2 = text.indexOf('\n',pos1, Qt::CaseSensitive) ) != -1 ){
+ setFormat( pos1 , pos2 , QColor(0,128,0));
+ pos += pos2 - pos1;
+ //setFormat( pos , text.length()-pos , _defaultColor );
+ } else{
+ setFormat( pos1 , text.length()-pos1, QColor(0,128,0));
+ pos += text.length()+1;
+ }
+ }
+}
+
+void QStyleModuleSyntaxHighlighter::highlightBlock ( const QString & text) {
+ setFormat( 0 , text.length() , _defaultColor );
+
+ highlightKeywords(text, _python, QColor(128,128,128));
+ highlightKeywords(text, _functors, QColor(136,0,0));
+ dynamicHighlight(text);
+ highlightKeywords(text, _operators, QColor(0,0,255));
+ highlightComment(text);
+} \ No newline at end of file
diff --git a/source/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.h b/source/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.h
new file mode 100755
index 00000000000..ff3591ac45d
--- /dev/null
+++ b/source/blender/freestyle/intern/app/QStyleModuleSyntaxHighlighter.h
@@ -0,0 +1,57 @@
+//
+// Filename : QStyleModuleSyntaxHighlighter.h
+// Author : Stephane Grabli
+// Purpose : Class to define the syntax highlighting
+// of the style module
+// Date of creation : 07/01/2004
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//
+// 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 QSTYLEMODULESYNTAXHIGHLIGHTER_H
+#define QSTYLEMODULESYNTAXHIGHLIGHTER_H
+
+#include <QSyntaxHighlighter>
+#include <vector>
+
+class QStyleModuleSyntaxHighlighter : public QSyntaxHighlighter
+{
+public:
+ QStyleModuleSyntaxHighlighter(QTextEdit *iTextEdit);
+ virtual ~QStyleModuleSyntaxHighlighter();
+
+ virtual void highlightBlock ( const QString & text) ;
+
+protected:
+ void highlightKeywords(const QString& text, std::vector<QString>& iKeywords, const QColor& iColor);
+ void dynamicHighlight(const QString& text);
+ void highlightComment(const QString& text);
+
+private:
+ std::vector<QString> _operators;
+ std::vector<QString> _functors;
+ std::vector<QString> _python;
+ QColor _defaultColor;
+};
+
+#endif
diff --git a/source/blender/freestyle/intern/app/app.pro b/source/blender/freestyle/intern/app/app.pro
new file mode 100755
index 00000000000..e2ba9aec6f7
--- /dev/null
+++ b/source/blender/freestyle/intern/app/app.pro
@@ -0,0 +1,179 @@
+# This file should be viewed as a -*- mode: Makefile -*-
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# W A R N I N G ! ! ! #
+# a u t h o r i z e d p e r s o n a l o n l y #
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+include(../Config.pri)
+
+TEMPLATE = app
+TARGET = $${APPNAME}
+debug: TARGET = $${TARGET}_d
+VERSION = $${APPVERSION}
+TARGET_VERSION_EXT = $${APPVERSION_MAJ}.$${APPVERSION_MID}
+
+
+
+#
+# CONFIG
+#
+#######################################
+
+CONFIG *= console qglviewer2 3ds$${LIB3DS_VERSION_MAJ}.$${LIB3DS_VERSION_MIN} python$${PYTHON_VERSION_MAJ}.$${PYTHON_VERSION_MIN} glut
+win32: CONFIG += embed_manifest_exe
+QT += xml
+
+exists (../libconfig.pri) {
+ include (../libconfig.pri)
+}
+
+#
+# BUILD DIRECTORIES
+#
+#######################################
+
+BUILD_DIR = ../../build
+
+OBJECTS_DIR = $${BUILD_DIR}/$${REL_OBJECTS_DIR}
+DESTDIR = $${BUILD_DIR}/$${REL_DESTDIR}
+UI_DIR = ui_dir
+
+#!win32:PYTHON_DIR_REL = build/$${REL_DESTDIR}/lib/python
+#win32:PYTHON_DIR_REL = build\\$${REL_DESTDIR}\\python
+
+#
+# LIBS
+#
+#######################################
+
+!static {
+ !win32 {
+ lib_bundle {
+ LIBS += -F$${BUILD_DIR}/$${REL_DESTDIR}/lib -framework $${LIB_GEOMETRY} -framework $${LIB_IMAGE} \
+ -framework $${LIB_SCENE_GRAPH} -framework $${LIB_SYSTEM} \
+ -framework $${LIB_WINGED_EDGE} -framework $${LIB_VIEW_MAP} \
+ -framework $${LIB_RENDERING} -framework $${LIB_STROKE}
+ } else {
+ LIBS *= -L$${BUILD_DIR}/$${REL_DESTDIR}/lib \
+ -l$${LIB_SYSTEM} -l$${LIB_IMAGE} -l$${LIB_GEOMETRY} \
+ -l$${LIB_SCENE_GRAPH} -l$${LIB_WINGED_EDGE} -l$${LIB_VIEW_MAP} \
+ -l$${LIB_RENDERING} -l$${LIB_STROKE}
+ }
+ }
+
+ win32:LIBS *= $${DESTDIR}/$${LIB_SCENE_GRAPH}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_SYSTEM}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_WINGED_EDGE}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_VIEW_MAP}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_STROKE}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_RENDERING}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_GEOMETRY}$${LIBVERSION}.lib \
+ $${DESTDIR}/$${LIB_IMAGE}$${LIBVERSION}.lib
+}
+
+# irix-n32:LIBS *= -l3ds -lglut -lQGLViewer -lpython$${PYTHON_VERSION_MAJ}.$${PYTHON_VERSION_MIN}
+# mac:LIBS *= -framework GLUT -lobjc -l3ds -lm -lQGLViewer -lpython$${PYTHON_VERSION_MAJ}.$${PYTHON_VERSION_MIN}
+
+#
+# INCLUDE PATH
+#
+#######################################
+
+#INCLUDEPATH *= ../geometry ../image ../scene_graph ../stroke ../system \
+# ../view_map ../winged_edge ../rendering
+
+#
+# DEFINES
+#
+#######################################
+
+DEFINES *= APPNAME=\\\"$${APPNAME}\\\" \
+ APPVERSION=\\\"$${APPVERSION}\\\" \
+ #ROOT_DIR=\\"$(FREESTYLE_DIR)\\" \
+ PYTHON_DIR_REL=\\\"$${PYTHON_DIR_REL}\\\"
+
+#
+# MOC DIRECTORY
+#
+#######################################
+
+win32:MOCEXT = win32
+linux-g++:MOCEXT = linux
+cygwin-g++:MOCEXT = cygwin
+irix-n32:MOCEXT = irix
+mac:MOCEXT = mac
+MOC_DIR = moc_$$MOCEXT
+
+#
+# INSTALL
+#
+#######################################
+
+EXE_DIR = ../../
+# install library
+target.path = $$EXE_DIR
+# "make install" configuration options
+INSTALLS += target
+
+#
+# SOURCES, HEADERS & FORMS
+#
+#######################################
+
+
+static {
+ include(../system/src.pri)
+ include(../image/src.pri)
+ include(../geometry/src.pri)
+ include(../scene_graph/src.pri)
+ include(../winged_edge/src.pri)
+ include(../view_map/src.pri)
+ include(../stroke/src.pri)
+ include(../rendering/src.pri)
+}
+#include(src.pri)
+APP_DIR = ../app
+DEPENDPATH += .
+INCLUDEPATH += .
+
+FORMS += appmainwindowbase4.ui \
+ interactiveshaderwindow4.ui \
+ optionswindow4.ui \
+ progressdialog4.ui \
+ stylewindow4.ui \
+ densitycurveswindow4.ui
+RESOURCES += $${APP_DIR}/freestyle.qrc
+SOURCES *= $${APP_DIR}/AppAboutWindow.cpp \
+ $${APP_DIR}/AppCanvas.cpp \
+ $${APP_DIR}/AppConfig.cpp \
+ $${APP_DIR}/AppGLWidget.cpp \
+ $${APP_DIR}/AppInteractiveShaderWindow.cpp \
+ $${APP_DIR}/AppMainWindow.cpp \
+ $${APP_DIR}/AppOptionsWindow.cpp \
+ $${APP_DIR}/AppProgressBar.cpp \
+ $${APP_DIR}/AppStyleWindow.cpp \
+ $${APP_DIR}/Controller.cpp \
+ $${APP_DIR}/QGLBasicWidget.cpp \
+ $${APP_DIR}/QStyleModuleSyntaxHighlighter.cpp \
+ $${APP_DIR}/AppGL2DCurvesViewer.cpp \
+ $${APP_DIR}/AppDensityCurvesWindow.cpp \
+ $${APP_DIR}/ConfigIO.cpp \
+ $${APP_DIR}/Main.cpp
+
+HEADERS *= $${APP_DIR}/AppAboutWindow.h \
+ $${APP_DIR}/AppCanvas.h \
+ $${APP_DIR}/AppConfig.h \
+ $${APP_DIR}/AppGLWidget.h \
+ $${APP_DIR}/AppInteractiveShaderWindow.h \
+ $${APP_DIR}/AppMainWindow.h \
+ $${APP_DIR}/AppOptionsWindow.h \
+ $${APP_DIR}/AppProgressBar.h \
+ $${APP_DIR}/AppStyleWindow.h \
+ $${APP_DIR}/QGLBasicWidget.h \
+ $${APP_DIR}/QStyleModuleSyntaxHighlighter.h \
+ $${APP_DIR}/AppGL2DCurvesViewer.h \
+ $${APP_DIR}/AppDensityCurvesWindow.h \
+ $${APP_DIR}/ConfigIO.h \
+ $${APP_DIR}/Controller.h
+
diff --git a/source/blender/freestyle/intern/app/appmainwindowbase4.ui b/source/blender/freestyle/intern/app/appmainwindowbase4.ui
new file mode 100755
index 00000000000..13e758d49dd
--- /dev/null
+++ b/source/blender/freestyle/intern/app/appmainwindowbase4.ui
@@ -0,0 +1,237 @@
+<ui version="4.0" >
+ <class>AppMainWindowBase</class>
+ <widget class="QMainWindow" name="AppMainWindowBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>510</width>
+ <height>523</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Freestyle</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>510</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuHelp" >
+ <property name="title" >
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="actionHelp" />
+ <addaction name="actionControlBindings" />
+ <addaction name="separator" />
+ <addaction name="actionAbout" />
+ </widget>
+ <widget class="QMenu" name="menuFile" >
+ <property name="title" >
+ <string>&amp;File</string>
+ </property>
+ <addaction name="actionOpen" />
+ <addaction name="actionSave" />
+ <addaction name="actionClose" />
+ <addaction name="separator" />
+ <addaction name="actionLoadCamera" />
+ <addaction name="separator" />
+ <addaction name="actionSaveSnapshot" />
+ <addaction name="actionSavePSSnapshot" />
+ <addaction name="actionSaveTextSnapshot" />
+ <addaction name="actionCaptureMovie" />
+ <addaction name="separator" />
+ <addaction name="actionQuit" />
+ </widget>
+ <widget class="QMenu" name="menuWindows" >
+ <property name="title" >
+ <string>&amp;Windows</string>
+ </property>
+ <addaction name="actionStyleModelerWindow" />
+ <addaction name="actionOptionsWindow" />
+ </widget>
+ <widget class="QMenu" name="menuTools" >
+ <property name="title" >
+ <string>&amp;Tools</string>
+ </property>
+ <addaction name="actionComputeViewMap" />
+ <addaction name="actionSaveDirectionalViewMapImages" />
+ <addaction name="actionComputeStrokes" />
+ <addaction name="separator" />
+ <addaction name="actionResetInterpreter" />
+ </widget>
+ <addaction name="menuFile" />
+ <addaction name="menuTools" />
+ <addaction name="menuWindows" />
+ <addaction name="menuHelp" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="actionOpen" >
+ <property name="text" >
+ <string>&amp;Open</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionSave" >
+ <property name="text" >
+ <string>&amp;Save</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="actionClose" >
+ <property name="text" >
+ <string>&amp;Close</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionLoadCamera" >
+ <property name="text" >
+ <string>Load Camera</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+L</string>
+ </property>
+ </action>
+ <action name="actionSavePSSnapshot" >
+ <property name="text" >
+ <string>Save PS Snapshot...</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+P</string>
+ </property>
+ </action>
+ <action name="actionSaveSnapshot" >
+ <property name="text" >
+ <string>Save Snapshot</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+W</string>
+ </property>
+ </action>
+ <action name="actionSaveTextSnapshot" >
+ <property name="text" >
+ <string>Save Text Snapshot</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+T</string>
+ </property>
+ </action>
+ <action name="actionCaptureMovie" >
+ <property name="text" >
+ <string>Capture Movie</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+M</string>
+ </property>
+ </action>
+ <action name="actionQuit" >
+ <property name="text" >
+ <string>&amp;Quit</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="actionComputeViewMap" >
+ <property name="text" >
+ <string>Compute View Map</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+B</string>
+ </property>
+ </action>
+ <action name="actionSaveDirectionalViewMapImages" >
+ <property name="text" >
+ <string>Save Directional ViewMap Images</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+Shift+B</string>
+ </property>
+ </action>
+ <action name="actionComputeStrokes" >
+ <property name="text" >
+ <string>Compute Strokes</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+D</string>
+ </property>
+ </action>
+ <action name="actionResetInterpreter" >
+ <property name="text" >
+ <string>Reset Interpreter</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+R</string>
+ </property>
+ </action>
+ <action name="actionStyleModelerWindow" >
+ <property name="text" >
+ <string>Style Modeler Window</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+I</string>
+ </property>
+ </action>
+ <action name="actionOptionsWindow" >
+ <property name="text" >
+ <string>Options Window</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+O</string>
+ </property>
+ </action>
+ <action name="actionHelp" >
+ <property name="text" >
+ <string>&amp;Help</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+H</string>
+ </property>
+ </action>
+ <action name="actionControlBindings" >
+ <property name="text" >
+ <string>Control Bindings</string>
+ </property>
+ <property name="shortcut" >
+ <string>H</string>
+ </property>
+ </action>
+ <action name="actionAbout" >
+ <property name="text" >
+ <string>About</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/source/blender/freestyle/intern/app/densitycurveswindow4.ui b/source/blender/freestyle/intern/app/densitycurveswindow4.ui
new file mode 100755
index 00000000000..1a35e3247d1
--- /dev/null
+++ b/source/blender/freestyle/intern/app/densitycurveswindow4.ui
@@ -0,0 +1,442 @@
+<ui version="4.0" >
+ <class>DensityCurvesWindow</class>
+ <widget class="QDialog" name="DensityCurvesWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>838</width>
+ <height>272</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Density Curves</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QTabWidget" name="tabWidget2" >
+ <property name="currentIndex" >
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>[ density / pyramid level ] for each Orientation</string>
+ </attribute>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="CurvesViewer0" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label0" >
+ <property name="text" >
+ <string>0 degree</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="CurvesViewer1" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label_45" >
+ <property name="text" >
+ <string>45 degrees</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="CurvesViewer2" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label90" >
+ <property name="text" >
+ <string>90 degrees</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="CurvesViewer3" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label135" >
+ <property name="text" >
+ <string>135 degrees</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="CurvesViewer4" />
+ </item>
+ <item>
+ <widget class="QLabel" name="labelAll" >
+ <property name="text" >
+ <string>all directions</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>[ density / orientation ] for each Level</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer1" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2" >
+ <property name="text" >
+ <string>level 1</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer2" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2" >
+ <property name="text" >
+ <string>level 2</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer3" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2_2" >
+ <property name="text" >
+ <string>level 3</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer4" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2_3" >
+ <property name="text" >
+ <string>level 4</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer5" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2_4" >
+ <property name="text" >
+ <string>level 5</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer6" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2_5" >
+ <property name="text" >
+ <string>level 6</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer7" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2_6" >
+ <property name="text" >
+ <string>level 7</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="AppGL2DCurvesViewer" native="1" name="LevelCurveViewer8" >
+ <property name="minimumSize" >
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label0_2_2_7" >
+ <property name="text" >
+ <string>level 8</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <customwidgets>
+ <customwidget>
+ <class>AppGL2DCurvesViewer</class>
+ <extends>QWidget</extends>
+ <header>AppGL2DCurvesViewer.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/source/blender/freestyle/intern/app/freestyle.qrc b/source/blender/freestyle/intern/app/freestyle.qrc
new file mode 100755
index 00000000000..b37a6702af6
--- /dev/null
+++ b/source/blender/freestyle/intern/app/freestyle.qrc
@@ -0,0 +1,23 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/icons" >
+ <file>icons/add.png</file>
+ <file>icons/arrow_down.png</file>
+ <file>icons/arrow_left.png</file>
+ <file>icons/arrow_right.png</file>
+ <file>icons/arrow_up.png</file>
+ <file>icons/clear.png</file>
+ <file>icons/close.png</file>
+ <file>icons/edit.png</file>
+ <file>icons/eye0.png</file>
+ <file>icons/eye1.png</file>
+ <file>icons/folder.png</file>
+ <file>icons/home.png</file>
+ <file>icons/mod0.png</file>
+ <file>icons/mod1.png</file>
+ <file>icons/ok.png</file>
+ <file>icons/reload.png</file>
+ <file>icons/remove.png</file>
+ <file>icons/save.png</file>
+ <file>icons/save_as.png</file>
+ </qresource>
+</RCC>
diff --git a/source/blender/freestyle/intern/app/icons/add.png b/source/blender/freestyle/intern/app/icons/add.png
new file mode 100755
index 00000000000..d3388dcb3a9
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/add.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/arrow_down.png b/source/blender/freestyle/intern/app/icons/arrow_down.png
new file mode 100755
index 00000000000..6cf2e9bba26
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/arrow_down.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/arrow_left.png b/source/blender/freestyle/intern/app/icons/arrow_left.png
new file mode 100755
index 00000000000..72a5c462af6
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/arrow_left.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/arrow_right.png b/source/blender/freestyle/intern/app/icons/arrow_right.png
new file mode 100755
index 00000000000..f7e5c3b37e3
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/arrow_right.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/arrow_up.png b/source/blender/freestyle/intern/app/icons/arrow_up.png
new file mode 100755
index 00000000000..993a574b15a
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/arrow_up.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/clear.png b/source/blender/freestyle/intern/app/icons/clear.png
new file mode 100755
index 00000000000..1e3b2e37bd9
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/clear.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/close.png b/source/blender/freestyle/intern/app/icons/close.png
new file mode 100755
index 00000000000..2042ec3d1ba
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/close.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/edit.png b/source/blender/freestyle/intern/app/icons/edit.png
new file mode 100755
index 00000000000..244751b1933
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/edit.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/eye0.png b/source/blender/freestyle/intern/app/icons/eye0.png
new file mode 100755
index 00000000000..5f6d873cb0c
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/eye0.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/eye1.png b/source/blender/freestyle/intern/app/icons/eye1.png
new file mode 100755
index 00000000000..f762b66b482
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/eye1.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/folder.png b/source/blender/freestyle/intern/app/icons/folder.png
new file mode 100755
index 00000000000..3a99ad5ee92
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/folder.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/home.png b/source/blender/freestyle/intern/app/icons/home.png
new file mode 100755
index 00000000000..ec4b22098b2
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/home.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/mod0.png b/source/blender/freestyle/intern/app/icons/mod0.png
new file mode 100755
index 00000000000..816d814528a
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/mod0.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/mod1.png b/source/blender/freestyle/intern/app/icons/mod1.png
new file mode 100755
index 00000000000..c7c66183800
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/mod1.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/ok.png b/source/blender/freestyle/intern/app/icons/ok.png
new file mode 100755
index 00000000000..31c064ba922
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/ok.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/reload.png b/source/blender/freestyle/intern/app/icons/reload.png
new file mode 100755
index 00000000000..d26c280f1ac
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/reload.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/remove.png b/source/blender/freestyle/intern/app/icons/remove.png
new file mode 100755
index 00000000000..86d8c38a7f8
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/remove.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/save.png b/source/blender/freestyle/intern/app/icons/save.png
new file mode 100755
index 00000000000..932100d98e9
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/save.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/icons/save_as.png b/source/blender/freestyle/intern/app/icons/save_as.png
new file mode 100755
index 00000000000..2c8b3f3e7b4
--- /dev/null
+++ b/source/blender/freestyle/intern/app/icons/save_as.png
Binary files differ
diff --git a/source/blender/freestyle/intern/app/interactiveshaderwindow4.ui b/source/blender/freestyle/intern/app/interactiveshaderwindow4.ui
new file mode 100755
index 00000000000..e17442ad43e
--- /dev/null
+++ b/source/blender/freestyle/intern/app/interactiveshaderwindow4.ui
@@ -0,0 +1,103 @@
+<ui version="4.0" >
+ <class>InteractiveShaderWindow</class>
+ <widget class="QDialog" name="InteractiveShaderWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>368</width>
+ <height>482</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>InteractiveShader</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="TextArea" />
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="OkButton" >
+ <property name="toolTip" >
+ <string>Save and close window</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/ok.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="SaveButton" >
+ <property name="toolTip" >
+ <string>Save module</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/save.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+S</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="SaveAsButton" >
+ <property name="toolTip" >
+ <string>Save module as</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/save_as.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+W</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="CancelButton" >
+ <property name="toolTip" >
+ <string>Close window</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/close.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+C</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources>
+ <include location="freestyle.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/source/blender/freestyle/intern/app/optionswindow4.ui b/source/blender/freestyle/intern/app/optionswindow4.ui
new file mode 100755
index 00000000000..48c322c6d84
--- /dev/null
+++ b/source/blender/freestyle/intern/app/optionswindow4.ui
@@ -0,0 +1,651 @@
+<ui version="4.0" >
+ <class>OptionsWindow</class>
+ <widget class="QDialog" name="OptionsWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>414</width>
+ <height>443</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Options</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>4</number>
+ </property>
+ <widget class="QWidget" name="directoriesTab" >
+ <attribute name="title" >
+ <string>Directories</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="modelsPathBox" >
+ <property name="title" >
+ <string>Models Path:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="modelsPathLineEdit" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="modelPathAddButton" >
+ <property name="toolTip" >
+ <string>Add a folder to the path...</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/folder.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="patternsPathBox" >
+ <property name="title" >
+ <string>Patterns Path:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="patternsPathLineEdit" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="patternsPathAddButton" >
+ <property name="toolTip" >
+ <string>Add a folder to the path...</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/folder.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="brushesPathBox" >
+ <property name="title" >
+ <string>Brushes Path:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="brushesPathLineEdit" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="brushesPathAddButton" >
+ <property name="toolTip" >
+ <string>Add a folder to the path...</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/folder.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="pythonPathBox" >
+ <property name="title" >
+ <string>Python Path:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="pythonPathLineEdit" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="pythonPathAddButton" >
+ <property name="toolTip" >
+ <string>Add a folder to the path...</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/folder.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="PaperTab" >
+ <attribute name="title" >
+ <string>Paper textures</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="paperTexturesList" />
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="addPaperTextureButton" >
+ <property name="toolTip" >
+ <string>Add Texture(s)</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/add.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removePaperTextureButton" >
+ <property name="toolTip" >
+ <string>Remove Texture</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/remove.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveUpPaperTextureButton" >
+ <property name="toolTip" >
+ <string>Move up</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/arrow_up.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveDownPaperTextureButton" >
+ <property name="toolTip" >
+ <string>Move down</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/arrow_down.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearPaperTextureButton" >
+ <property name="toolTip" >
+ <string>Clear list</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/clear.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="featureLineTab" >
+ <attribute name="title" >
+ <string>Feature Lines</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="curvaturesBox" >
+ <property name="title" >
+ <string>Curvatures</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="sphereRadiusLabel" >
+ <property name="text" >
+ <string>Sphere Radius (x mean edge size)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="sphereRadiusLineEdit" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="ridgesAndValleysBox" >
+ <property name="title" >
+ <string>Ridges and Valleys</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QCheckBox" name="ridgeValleyCheckBox" >
+ <property name="text" >
+ <string>Compute Ridges and Valleys</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="suggestiveContoursBox" >
+ <property name="title" >
+ <string>Suggestive Contours</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="suggestiveContoursCheckBox" >
+ <property name="text" >
+ <string>Compute Suggestive Contours</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="krEpsilonLabel" >
+ <property name="text" >
+ <string>kr Derivative Epsilon</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="krEpsilonLineEdit" />
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="miscelleanousTab" >
+ <attribute name="title" >
+ <string>Miscelleanous</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="viewMapBox" >
+ <property name="title" >
+ <string>View Map</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="asFloatCheckBox" >
+ <property name="text" >
+ <string>Save vector coordinates as floats</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="noOccluderListCheckBox" >
+ <property name="text" >
+ <string>Do not save occluders lists</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="steerableViewMapCheckBox" >
+ <property name="text" >
+ <string>Compute Steerable ViewMap</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="visibilityBox" >
+ <property name="title" >
+ <string>Visibility</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="qiCheckBox" >
+ <property name="text" >
+ <string>Enable Quantitative Invisibility</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="drawingBox" >
+ <property name="title" >
+ <string>Drawing</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="backBufferCheckBox" >
+ <property name="text" >
+ <string>Back Buffer</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="frontBufferCheckBox" >
+ <property name="text" >
+ <string>Front Buffer</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="helpTab" >
+ <attribute name="title" >
+ <string>Help</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="browserCmdLabel" >
+ <property name="text" >
+ <string>Browser Command</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="browserCmdLineEdit" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="helpBox" >
+ <property name="title" >
+ <string>Help index file:</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="helpIndexPathLineEdit" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="helpIndexPathButton" >
+ <property name="toolTip" >
+ <string>Browse</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/folder.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="toolTip" >
+ <string>Save and close window</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/ok.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="toolTip" >
+ <string>Save Options</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/save.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton" >
+ <property name="toolTip" >
+ <string>Close window</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/close.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="freestyle.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/source/blender/freestyle/intern/app/progressdialog4.ui b/source/blender/freestyle/intern/app/progressdialog4.ui
new file mode 100755
index 00000000000..78cc67ed440
--- /dev/null
+++ b/source/blender/freestyle/intern/app/progressdialog4.ui
@@ -0,0 +1,26 @@
+<ui version="4.0" stdsetdef="1" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>ProgressDialog</class>
+ <widget class="QDialog" name="ProgressDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>64</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Progress Dialog</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="Q3ProgressBar" name="ProgressBar2" />
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+</ui>
diff --git a/source/blender/freestyle/intern/app/src.pri b/source/blender/freestyle/intern/app/src.pri
new file mode 100755
index 00000000000..2fcc9146216
--- /dev/null
+++ b/source/blender/freestyle/intern/app/src.pri
@@ -0,0 +1,50 @@
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# W A R N I N G ! ! ! #
+# a u t h o r i z e d p e r s o n a l o n l y #
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+APP_DIR = ../app
+
+SOURCES *= $${APP_DIR}/AppAboutWindow.cpp \
+ $${APP_DIR}/AppCanvas.cpp \
+ $${APP_DIR}/AppConfig.cpp \
+ $${APP_DIR}/AppGLWidget.cpp \
+ $${APP_DIR}/AppInteractiveShaderWindow.cpp \
+ $${APP_DIR}/AppMainWindow.cpp \
+ $${APP_DIR}/AppOptionsWindow.cpp \
+ $${APP_DIR}/AppProgressBar.cpp \
+ $${APP_DIR}/AppStyleWindow.cpp \
+ $${APP_DIR}/Controller.cpp \
+ $${APP_DIR}/QGLBasicWidget.cpp \
+ $${APP_DIR}/QStyleModuleSyntaxHighlighter.cpp \
+ $${APP_DIR}/AppGL2DCurvesViewer.cpp \
+ $${APP_DIR}/AppDensityCurvesWindow.cpp \
+ $${APP_DIR}/ConfigIO.cpp \
+ $${APP_DIR}/Main.cpp
+
+HEADERS *= $${APP_DIR}/AppAboutWindow.h \
+ $${APP_DIR}/AppCanvas.h \
+ $${APP_DIR}/AppConfig.h \
+ $${APP_DIR}/AppGLWidget.h \
+ $${APP_DIR}/AppInteractiveShaderWindow.h \
+ $${APP_DIR}/AppMainWindow.h \
+ $${APP_DIR}/AppOptionsWindow.h \
+ $${APP_DIR}/AppProgressBar.h \
+ $${APP_DIR}/AppStyleWindow.h \
+ $${APP_DIR}/QGLBasicWidget.h \
+ $${APP_DIR}/QStyleModuleSyntaxHighlighter.h \
+ $${APP_DIR}/AppGL2DCurvesViewer.h \
+ $${APP_DIR}/AppDensityCurvesWindow.h \
+ $${APP_DIR}/ConfigIO.h \
+ $${APP_DIR}/Controller.h
+
+FORMS *= $${APP_DIR}/appmainwindowbase4.ui \
+ $${APP_DIR}/interactiveshaderwindow4.ui \
+ $${APP_DIR}/optionswindow4.ui \
+ $${APP_DIR}/progressdialog4.ui \
+ $${APP_DIR}/stylewindow4.ui \
+ $${APP_DIR}/densitycurveswindow4.ui
+
+RESOURCES = $${APP_DIR}/freestyle.qrc
+
+
diff --git a/source/blender/freestyle/intern/app/stylewindow4.ui b/source/blender/freestyle/intern/app/stylewindow4.ui
new file mode 100755
index 00000000000..c4ff5f656ae
--- /dev/null
+++ b/source/blender/freestyle/intern/app/stylewindow4.ui
@@ -0,0 +1,182 @@
+<ui version="4.0" >
+ <class>StyleWindow</class>
+ <widget class="QDialog" name="StyleWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>571</width>
+ <height>421</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Style Modules</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTableWidget" name="PlayList" >
+ <property name="dragEnabled" >
+ <bool>false</bool>
+ </property>
+ <property name="rowCount" >
+ <number>0</number>
+ </property>
+ <property name="columnCount" >
+ <number>3</number>
+ </property>
+ <column/>
+ <column/>
+ <column/>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="addButton" >
+ <property name="toolTip" >
+ <string>Add a Style Module</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/add.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+A</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeButton" >
+ <property name="toolTip" >
+ <string>Remove a Style Module</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/remove.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+R</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveUpButton" >
+ <property name="toolTip" >
+ <string>Move up</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/arrow_up.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+U</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveDownButton" >
+ <property name="toolTip" >
+ <string>Move down</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/arrow_down.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="editButton" >
+ <property name="toolTip" >
+ <string>Edit Style Module</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/edit.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+E</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="saveButton" >
+ <property name="toolTip" >
+ <string>Save Modules list</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/save.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+S</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton" >
+ <property name="toolTip" >
+ <string>Clear Modules list</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/clear.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+X</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton" >
+ <property name="toolTip" >
+ <string>Close window</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="freestyle.qrc" >:/icons/icons/close.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+C</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="freestyle.qrc" />
+ </resources>
+ <connections/>
+</ui>