diff options
author | Maxime Curioni <maxime.curioni@gmail.com> | 2008-05-08 23:16:40 +0400 |
---|---|---|
committer | Maxime Curioni <maxime.curioni@gmail.com> | 2008-05-08 23:16:40 +0400 |
commit | 64e4a3ec9aed6c8abe095e2cd1fe1552f7cde51c (patch) | |
tree | 6c77358bd447b6c2d215324ef48fc12d1f5ae5ca /source/blender/freestyle/intern/app | |
parent | cf2e1e2857cfc5b3c2848c7fc6c9d919ac72fabb (diff) | |
parent | 106974a9d2d5caa5188322507980e3d57d2e3517 (diff) |
soc-2008-mxcurioni: merged changes to revision 14747, cosmetic changes for source/blender/freestyle
Diffstat (limited to 'source/blender/freestyle/intern/app')
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>&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>&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>&Windows</string> + </property> + <addaction name="actionStyleModelerWindow" /> + <addaction name="actionOptionsWindow" /> + </widget> + <widget class="QMenu" name="menuTools" > + <property name="title" > + <string>&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>&Open</string> + </property> + <property name="shortcut" > + <string>Ctrl+O</string> + </property> + </action> + <action name="actionSave" > + <property name="text" > + <string>&Save</string> + </property> + <property name="shortcut" > + <string>Ctrl+S</string> + </property> + </action> + <action name="actionClose" > + <property name="text" > + <string>&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>&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>&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 Binary files differnew file mode 100755 index 00000000000..d3388dcb3a9 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/add.png diff --git a/source/blender/freestyle/intern/app/icons/arrow_down.png b/source/blender/freestyle/intern/app/icons/arrow_down.png Binary files differnew file mode 100755 index 00000000000..6cf2e9bba26 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/arrow_down.png diff --git a/source/blender/freestyle/intern/app/icons/arrow_left.png b/source/blender/freestyle/intern/app/icons/arrow_left.png Binary files differnew file mode 100755 index 00000000000..72a5c462af6 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/arrow_left.png diff --git a/source/blender/freestyle/intern/app/icons/arrow_right.png b/source/blender/freestyle/intern/app/icons/arrow_right.png Binary files differnew file mode 100755 index 00000000000..f7e5c3b37e3 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/arrow_right.png diff --git a/source/blender/freestyle/intern/app/icons/arrow_up.png b/source/blender/freestyle/intern/app/icons/arrow_up.png Binary files differnew file mode 100755 index 00000000000..993a574b15a --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/arrow_up.png diff --git a/source/blender/freestyle/intern/app/icons/clear.png b/source/blender/freestyle/intern/app/icons/clear.png Binary files differnew file mode 100755 index 00000000000..1e3b2e37bd9 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/clear.png diff --git a/source/blender/freestyle/intern/app/icons/close.png b/source/blender/freestyle/intern/app/icons/close.png Binary files differnew file mode 100755 index 00000000000..2042ec3d1ba --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/close.png diff --git a/source/blender/freestyle/intern/app/icons/edit.png b/source/blender/freestyle/intern/app/icons/edit.png Binary files differnew file mode 100755 index 00000000000..244751b1933 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/edit.png diff --git a/source/blender/freestyle/intern/app/icons/eye0.png b/source/blender/freestyle/intern/app/icons/eye0.png Binary files differnew file mode 100755 index 00000000000..5f6d873cb0c --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/eye0.png diff --git a/source/blender/freestyle/intern/app/icons/eye1.png b/source/blender/freestyle/intern/app/icons/eye1.png Binary files differnew file mode 100755 index 00000000000..f762b66b482 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/eye1.png diff --git a/source/blender/freestyle/intern/app/icons/folder.png b/source/blender/freestyle/intern/app/icons/folder.png Binary files differnew file mode 100755 index 00000000000..3a99ad5ee92 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/folder.png diff --git a/source/blender/freestyle/intern/app/icons/home.png b/source/blender/freestyle/intern/app/icons/home.png Binary files differnew file mode 100755 index 00000000000..ec4b22098b2 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/home.png diff --git a/source/blender/freestyle/intern/app/icons/mod0.png b/source/blender/freestyle/intern/app/icons/mod0.png Binary files differnew file mode 100755 index 00000000000..816d814528a --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/mod0.png diff --git a/source/blender/freestyle/intern/app/icons/mod1.png b/source/blender/freestyle/intern/app/icons/mod1.png Binary files differnew file mode 100755 index 00000000000..c7c66183800 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/mod1.png diff --git a/source/blender/freestyle/intern/app/icons/ok.png b/source/blender/freestyle/intern/app/icons/ok.png Binary files differnew file mode 100755 index 00000000000..31c064ba922 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/ok.png diff --git a/source/blender/freestyle/intern/app/icons/reload.png b/source/blender/freestyle/intern/app/icons/reload.png Binary files differnew file mode 100755 index 00000000000..d26c280f1ac --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/reload.png diff --git a/source/blender/freestyle/intern/app/icons/remove.png b/source/blender/freestyle/intern/app/icons/remove.png Binary files differnew file mode 100755 index 00000000000..86d8c38a7f8 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/remove.png diff --git a/source/blender/freestyle/intern/app/icons/save.png b/source/blender/freestyle/intern/app/icons/save.png Binary files differnew file mode 100755 index 00000000000..932100d98e9 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/save.png diff --git a/source/blender/freestyle/intern/app/icons/save_as.png b/source/blender/freestyle/intern/app/icons/save_as.png Binary files differnew file mode 100755 index 00000000000..2c8b3f3e7b4 --- /dev/null +++ b/source/blender/freestyle/intern/app/icons/save_as.png 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> |