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