e26e001e5abbd7cdfb4bdacd4b72d0c0dfe7e794
[blender-staging.git] / source / blender / freestyle / intern / application / Controller.cpp
1
2 //
3 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
4 //   with this source distribution. 
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 ///////////////////////////////////////////////////////////////////////////////
21
22 // Must be included before any QT header, because of moc
23 #include "../system/PythonInterpreter.h"
24
25 #include <string>
26 #include <fstream>
27 #include <float.h>
28
29 #include "AppView.h"
30 #include "AppCanvas.h"
31 #include "AppConfig.h"
32
33
34 #include "../system/StringUtils.h"
35 #include "../scene_graph/NodeShape.h"
36 #include "../scene_graph/NodeTransform.h"
37 #include "../scene_graph/NodeDrawingStyle.h"
38 #include "../winged_edge/WingedEdgeBuilder.h"
39 #include "../winged_edge/WEdge.h"
40 #include "../scene_graph/VertexRep.h"
41 #include "../winged_edge/WXEdgeBuilder.h"
42 #include "../scene_graph/ScenePrettyPrinter.h"
43 #include "../winged_edge/WFillGrid.h"
44
45 #include "../view_map/ViewMapTesselator.h"
46 #include "../stroke/StrokeTesselator.h"
47 #include "../view_map/ViewMapIO.h"
48 #include "Controller.h"
49 #include "../view_map/ViewMap.h"
50 #include "../winged_edge/Curvature.h"
51 #include "../image/Image.h"
52 #include "../view_map/SteerableViewMap.h"
53 #include "../stroke/PSStrokeRenderer.h"
54 #include "../stroke/TextStrokeRenderer.h"
55 #include "../stroke/StyleModule.h"
56
57 #include "../system/StringUtils.h"
58
59 #include "../blender_interface/BlenderFileLoader.h"
60 #include "../blender_interface/BlenderStrokeRenderer.h"
61 #include "../blender_interface/BlenderStyleModule.h"
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67         #include "../../FRS_freestyle.h"
68
69 #ifdef __cplusplus
70 }
71 #endif
72
73
74
75 Controller::Controller()
76 {
77         
78   const string sep(Config::DIR_SEP.c_str());
79   //const string filename = Config::Path::getInstance()->getHomeDir() + sep + Config::OPTIONS_DIR + sep + Config::OPTIONS_CURRENT_DIRS_FILE;
80   //_current_dirs = new ConfigIO(filename, Config::APPLICATION_NAME + "CurrentDirs", true);
81
82   _RootNode = new NodeGroup;
83   _RootNode->addRef();
84   
85   _SilhouetteNode = NULL;
86   //_ProjectedSilhouette = NULL;
87   //_VisibleProjectedSilhouette = NULL;
88   
89   _DebugNode = new NodeGroup;
90   _DebugNode->addRef();
91
92   _winged_edge = NULL;
93   
94   _pView = NULL;
95
96   _edgeTesselationNature = (Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE);
97
98   _ProgressBar = new ProgressBar;
99   _SceneNumFaces = 0;
100   _minEdgeSize = DBL_MAX;
101   _EPSILON = 1e-6;
102   _bboxDiag = 0;
103   
104   _ViewMap = 0;
105
106   _Canvas = 0;
107
108   _VisibilityAlgo = ViewMapBuilder::ray_casting;
109   //_VisibilityAlgo = ViewMapBuilder::ray_casting_fast;
110
111   _Canvas = new AppCanvas;
112
113   _inter = new PythonInterpreter();
114   _EnableQI = true;
115   _ComputeRidges = true;
116   _ComputeSteerableViewMap = false;
117   _ComputeSuggestive = true;
118   _ComputeMaterialBoundaries = true;
119   _sphereRadius = 1.0;
120   _creaseAngle = 134.43;
121
122         init_options();
123 }
124
125 Controller::~Controller()
126 {
127   if(NULL != _RootNode)
128     {
129       int ref = _RootNode->destroy();
130       if(0 == ref)
131         delete _RootNode;
132     }
133   
134   if(NULL != _SilhouetteNode)
135     {
136       int ref = _SilhouetteNode->destroy();
137       if(0 == ref)
138         delete _SilhouetteNode;
139     }
140   
141   if(NULL != _DebugNode)
142     {
143       int ref = _DebugNode->destroy();
144       if(0 == ref)
145         delete _DebugNode;
146     }
147
148   if(_winged_edge) {
149     delete _winged_edge;
150     _winged_edge = NULL;
151   }
152
153   if(0 != _ViewMap)
154     {
155       delete _ViewMap;
156       _ViewMap = 0;
157     }
158
159   if(0 != _Canvas)
160     {
161       delete _Canvas;
162       _Canvas = 0;
163     }
164
165   if (_inter) {
166     delete _inter;
167     _inter = NULL;
168   }
169
170   //delete _current_dirs;
171 }
172
173 void Controller::setView(AppView *iView)
174 {
175   if(NULL == iView)
176     return;
177   
178   _pView = iView;
179   _Canvas->setViewer(_pView);
180 }
181
182 void Controller::setPassDiffuse(float *buf, int width, int height)
183 {
184   AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas);
185   assert(app_canvas != 0);
186   app_canvas->setPassDiffuse(buf, width, height);
187 }
188
189 void Controller::setPassZ(float *buf, int width, int height)
190 {
191   AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas);
192   assert(app_canvas != 0);
193   app_canvas->setPassZ(buf, width, height);
194 }
195
196 void Controller::setContext(bContext *C)
197 {
198   PythonInterpreter* py_inter = dynamic_cast<PythonInterpreter*>(_inter);
199   assert(py_inter != 0);
200   py_inter->setContext(C);
201 }
202
203 int Controller::LoadMesh(Render *re, SceneRenderLayer* srl)
204 {
205   
206   BlenderFileLoader loader(re, srl);
207   
208   _Chrono.start();
209   
210   NodeGroup *blenderScene = loader.Load();
211
212   if (blenderScene == NULL) {
213         cout << "Cannot load scene" << endl;
214     return 1;
215   }
216
217         if( blenderScene->numberOfChildren() < 1) {
218                 cout << "Empty scene" << endl;
219                 blenderScene->destroy();
220                 delete blenderScene;
221                 return 1;
222         }
223
224           cout << "Scene loaded" << endl;
225   printf("Mesh cleaning    : %lf\n", _Chrono.stop());
226   _SceneNumFaces += loader.numFacesRead();
227
228   if(loader.minEdgeSize() < _minEdgeSize)
229     {
230       _minEdgeSize = loader.minEdgeSize();
231     }
232
233   // DEBUG
234   // ScenePrettyPrinter spp;
235   // blenderScene->accept(spp);
236         
237   _RootNode->AddChild(blenderScene);
238   _RootNode->UpdateBBox(); // FIXME: Correct that by making a Renderer to compute the bbox
239
240   _pView->setModel(_RootNode);
241   //_pView->FitBBox();
242
243
244   _Chrono.start();
245
246   
247   WXEdgeBuilder wx_builder;
248   blenderScene->accept(wx_builder);
249   _winged_edge = wx_builder.getWingedEdge();
250
251   printf("WEdge building   : %lf\n", _Chrono.stop());
252
253  _Chrono.start();
254
255   _Grid.clear();
256   Vec3r size;
257   for(unsigned int i=0; i<3; i++)
258     {
259       size[i] = fabs(_RootNode->bbox().getMax()[i] - _RootNode->bbox().getMin()[i]);
260       size[i] += size[i]/10.0; // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections
261       if(size[i]==0){
262           cout << "Warning: the bbox size is 0 in dimension "<<i<<endl;
263       }
264     }
265   _Grid.configure(Vec3r(_RootNode->bbox().getMin() - size / 20.0), size,
266                   _SceneNumFaces);
267
268   // Fill in the grid:
269   WFillGrid fillGridRenderer(&_Grid, _winged_edge);
270   fillGridRenderer.fillGrid();
271
272   printf("Grid building    : %lf\n", _Chrono.stop());
273   
274   // DEBUG
275   _Grid.displayDebug();
276   //  
277   // _pView->setDebug(_DebugNode);
278
279   //delete stuff
280   //  if(0 != ws_builder)
281   //    {
282   //      delete ws_builder;
283   //      ws_builder = 0;
284   //    }
285
286         //soc QFileInfo qfi(iFileName);
287         //soc string basename((const char*)qfi.fileName().toAscii().data());
288         // char cleaned[FILE_MAX];
289         // BLI_strncpy(cleaned, iFileName, FILE_MAX);
290         // BLI_cleanup_file(NULL, cleaned);
291         // string basename = StringUtils::toAscii( string(cleaned) );
292
293   _ListOfModels.push_back("Blender_models");
294
295   cout << "Triangles nb     : " << _SceneNumFaces << endl;
296   _bboxDiag = (_RootNode->bbox().getMax()-_RootNode->bbox().getMin()).norm();
297   cout << "Bounding Box     : " << _bboxDiag << endl;
298   return 0;
299 }
300
301
302 void Controller::CloseFile()
303 {
304   WShape::setCurrentId(0);
305   _pView->DetachModel();
306   _ListOfModels.clear();
307   if(NULL != _RootNode)
308     {
309       int ref = _RootNode->destroy();
310       if(0 == ref)
311         _RootNode->addRef();
312     
313       _RootNode->clearBBox();
314     }
315   
316   _pView->DetachSilhouette();
317   if (NULL != _SilhouetteNode)
318     {
319       int ref = _SilhouetteNode->destroy();
320       if(0 == ref)
321         {
322           delete _SilhouetteNode;
323           _SilhouetteNode = NULL;
324         }
325     }
326   //  if(NULL != _ProjectedSilhouette)
327   //    {
328   //      int ref = _ProjectedSilhouette->destroy();
329   //      if(0 == ref)
330   //    {
331   //      delete _ProjectedSilhouette;
332   //      _ProjectedSilhouette = NULL;
333   //    }
334   //    }
335   //  if(NULL != _VisibleProjectedSilhouette)
336   //    {
337   //      int ref = _VisibleProjectedSilhouette->destroy();
338   //      if(0 == ref)
339   //    {
340   //      delete _VisibleProjectedSilhouette;
341   //      _VisibleProjectedSilhouette = NULL;
342   //    }
343   //  }
344   
345   _pView->DetachDebug();
346   if(NULL != _DebugNode)
347     {
348       int ref = _DebugNode->destroy();
349       if(0 == ref)
350         _DebugNode->addRef();
351     }
352   
353   if(_winged_edge) {
354     delete _winged_edge;
355     _winged_edge = NULL;
356   }
357
358   // We deallocate the memory:
359   if(NULL != _ViewMap)
360     {
361       delete _ViewMap;
362       _ViewMap = 0;
363     }
364
365   // clears the canvas
366   _Canvas->Clear();
367
368   // clears the grid
369   _Grid.clear();
370   _SceneNumFaces = 0;
371   _minEdgeSize = DBL_MAX;
372
373   // soc: reset passes
374   setPassDiffuse(NULL, 0, 0);
375   setPassZ(NULL, 0, 0);
376 }
377
378
379
380 void Controller::ComputeViewMap()
381 {
382
383   if (!_ListOfModels.size())
384     return;
385   
386   if(NULL != _ViewMap)
387     {
388       delete _ViewMap;
389       _ViewMap = 0;
390     }
391
392   _pView->DetachDebug();
393   if(NULL != _DebugNode)
394     {
395       int ref = _DebugNode->destroy();
396       if(0 == ref)
397         _DebugNode->addRef();
398     }
399   
400
401   _pView->DetachSilhouette();
402   if (NULL != _SilhouetteNode)
403     {
404       int ref = _SilhouetteNode->destroy();
405       if(0 == ref)
406         delete _SilhouetteNode;
407     }
408   //  if(NULL != _ProjectedSilhouette)
409   //    {
410   //      int ref = _ProjectedSilhouette->destroy();
411   //      if(0 == ref)
412   //    delete _ProjectedSilhouette;
413   //    }
414   //  if(NULL != _VisibleProjectedSilhouette)
415   //    {
416   //      int ref = _VisibleProjectedSilhouette->destroy();
417   //      if(0 == ref)
418   //    {
419   //      delete _VisibleProjectedSilhouette;
420   //      _VisibleProjectedSilhouette = 0;
421   //    }
422   //  }
423   
424   // retrieve the 3D viewpoint and transformations information
425   //----------------------------------------------------------
426   // Save the viewpoint context at the view level in order 
427   // to be able to restore it later:
428
429   // Restore the context of view:
430   // we need to perform all these operations while the 
431   // 3D context is on.
432   Vec3r vp( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]);
433
434         //cout << "mv" << endl;
435         real mv[4][4];
436         for( int i= 0; i < 4; i++) {
437                 for( int j= 0; j < 4; j++) {
438                         mv[i][j] = freestyle_mv[i][j];
439                         //cout << mv[i][j] << " ";
440                 }
441         //      cout << endl;
442         }
443         
444         //cout << "\nproj" << endl;
445         real proj[4][4];
446         for( int i= 0; i < 4; i++) {
447                 for( int j= 0; j < 4; j++) {
448                         proj[i][j] = freestyle_proj[i][j];
449                         //cout << proj[i][j] << " ";
450                 }
451                 //cout << endl;
452         }
453
454         int viewport[4];
455         for( int i= 0; i < 4; i++)
456                 viewport[i] = freestyle_viewport[i];
457         
458         //cout << "\nfocal:" << _pView->GetFocalLength() << endl << endl;
459
460
461
462   // Flag the WXEdge structure for silhouette edge detection:
463   //----------------------------------------------------------
464
465         cout << "\n===  Detecting silhouette edges  ===" << endl;
466   _Chrono.start();
467  
468   edgeDetector.setViewpoint(Vec3r(vp));
469   edgeDetector.enableOrthographicProjection(proj[3][3] != 0.0);
470   edgeDetector.enableRidgesAndValleysFlag(_ComputeRidges);
471   edgeDetector.enableSuggestiveContours(_ComputeSuggestive);
472   edgeDetector.enableMaterialBoundaries(_ComputeMaterialBoundaries);
473   edgeDetector.setCreaseAngle(_creaseAngle);
474   edgeDetector.setSphereRadius(_sphereRadius);
475   edgeDetector.setSuggestiveContourKrDerivativeEpsilon(_suggestiveContourKrDerivativeEpsilon);
476   edgeDetector.processShapes(*_winged_edge);
477
478   real duration = _Chrono.stop();
479   printf("Feature lines    : %lf\n", duration);
480
481   // Builds the view map structure from the flagged WSEdge structure:
482   //----------------------------------------------------------
483   ViewMapBuilder vmBuilder;
484   vmBuilder.setEnableQI(_EnableQI);
485   vmBuilder.setViewpoint(Vec3r(vp));
486   vmBuilder.setTransform( mv, proj,viewport, _pView->GetFocalLength(), _pView->GetAspect(), _pView->GetFovyRadian());
487   vmBuilder.setFrustum(_pView->znear(), _pView->zfar());  
488   vmBuilder.setGrid(&_Grid);
489   
490   // Builds a tesselated form of the silhouette for display purpose:
491   //---------------------------------------------------------------
492   ViewMapTesselator3D sTesselator3d;
493   //ViewMapTesselator2D sTesselator2d;
494   //sTesselator2d.setNature(_edgeTesselationNature);
495   sTesselator3d.setNature(_edgeTesselationNature);
496     
497         cout << "\n===  Building the view map  ===" << endl;
498   _Chrono.start();
499   // Build View Map
500   _ViewMap = vmBuilder.BuildViewMap(*_winged_edge, _VisibilityAlgo, _EPSILON);
501   _ViewMap->setScene3dBBox(_RootNode->bbox());
502   
503         printf("ViewMap edge count : %i\n", _ViewMap->viewedges_size() );
504
505   //Tesselate the 3D edges:
506   _SilhouetteNode = sTesselator3d.Tesselate(_ViewMap);
507   _SilhouetteNode->addRef();
508   
509   // Tesselate 2D edges
510   //  _ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap);
511   //  _ProjectedSilhouette->addRef();
512   
513   duration = _Chrono.stop();
514   printf("ViewMap building : %lf\n", duration);
515
516   
517   _pView->AddSilhouette(_SilhouetteNode);
518   //_pView->AddSilhouette(_WRoot);
519   //_pView->Add2DSilhouette(_ProjectedSilhouette);
520   //_pView->Add2DVisibleSilhouette(_VisibleProjectedSilhouette);  
521   _pView->AddDebug(_DebugNode);
522
523   // Draw the steerable density map:
524   //--------------------------------
525   if(_ComputeSteerableViewMap){
526     ComputeSteerableViewMap();
527   }
528   // Reset Style modules modification flags
529   resetModified(true);
530 }
531
532 void Controller::ComputeSteerableViewMap(){
533 //soc
534   // if((!_Canvas) || (!_ViewMap))
535   //   return;
536   //   
537   // // Build 4 nodes containing the edges in the 4 directions
538   // NodeGroup *ng[Canvas::NB_STEERABLE_VIEWMAP];
539   // unsigned i;
540   // real c = 32.f/255.f; // see SteerableViewMap::readSteerableViewMapPixel() for information about this 32.
541   // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){
542   //   ng[i] = new NodeGroup;
543   // }
544   // NodeShape *completeNS = new NodeShape;
545   // completeNS->material().setDiffuse(c,c,c,1);
546   // ng[Canvas::NB_STEERABLE_VIEWMAP-1]->AddChild(completeNS);
547   // SteerableViewMap * svm = _Canvas->getSteerableViewMap();
548   // svm->Reset();
549   // 
550   // ViewMap::fedges_container& fedges = _ViewMap->FEdges();
551   // LineRep * fRep;
552   // NodeShape *ns;
553   // for(ViewMap::fedges_container::iterator f=fedges.begin(), fend=fedges.end();
554   // f!=fend;
555   // ++f){
556   //   if((*f)->viewedge()->qi() != 0)
557   //     continue;
558   //   fRep = new LineRep((*f)->vertexA()->point2d(),(*f)->vertexB()->point2d()) ;
559   //   completeNS->AddRep(fRep); // add to the complete map anyway
560   //   double *oweights = svm->AddFEdge(*f);
561   //   for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP-1; ++i){
562   //     ns = new NodeShape;
563   //     double wc = oweights[i]*c;
564   //     if(oweights[i] == 0)
565   //       continue;
566   //     ns->material().setDiffuse(wc, wc, wc, 1);
567   //     ns->AddRep(fRep);
568   //     ng[i]->AddChild(ns);
569   //   }
570   // }
571   // 
572   // GrayImage *img[Canvas::NB_STEERABLE_VIEWMAP];
573   // //#ifdef WIN32
574   // QGLBasicWidget offscreenBuffer(_pView, "SteerableViewMap", _pView->width(), _pView->height()); 
575   // QPixmap pm;
576   // QImage qimg;
577   // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){
578   //   offscreenBuffer.AddNode(ng[i]);
579   //   //img[i] = new GrayImage(_pView->width(), _pView->height());
580   //   //offscreenBuffer.readPixels(0,0,_pView->width(), _pView->height(), img[i]->getArray());
581   //   pm = offscreenBuffer.renderPixmap(_pView->width(), _pView->height());
582   // 
583   //   if(pm.isNull())
584   //     cout << "BuildViewMap Warning: couldn't render the steerable ViewMap" << endl;
585   //   //pm.save(QString("steerable")+QString::number(i)+QString(".bmp"), "BMP");
586   //   // FIXME!! Lost of time !
587   //   qimg = pm.toImage();
588   //   // FIXME !! again!
589   //   img[i] = new GrayImage(_pView->width(), _pView->height());
590   //   for(unsigned y=0;y<img[i]->height();++y){
591   //     for(unsigned x=0;x<img[i]->width();++x){
592   //       //img[i]->setPixel(x,y,(float)qGray(qimg.pixel(x,y))/255.f);
593   //       img[i]->setPixel(x,y,(float)qGray(qimg.pixel(x,y)));
594   //       //        float c = qGray(qimg.pixel(x,y));
595   //       //        img[i]->setPixel(x,y,qGray(qimg.pixel(x,y)));
596   //     }
597   //   }
598   //   offscreenBuffer.DetachNode(ng[i]);
599   //   ng[i]->destroy();
600   //   delete ng[i];
601   //   // check
602   //   //    qimg = QImage(_pView->width(), _pView->height(), 32);
603   //   //    for(y=0;y<img[i]->height();++y){
604   //   //      for(unsigned x=0;x<img[i]->width();++x){
605   //   //        float v = img[i]->pixel(x,y);
606   //   //        qimg.setPixel(x,y,qRgb(v,v,v));
607   //   //      }
608   //   //    }
609   //   //    qimg.save(QString("newsteerable")+QString::number(i)+QString(".bmp"), "BMP");
610   // }
611   // 
612   // 
613   // svm->buildImagesPyramids(img,false,0,1.f);
614 }
615
616 void Controller::saveSteerableViewMapImages(){
617   SteerableViewMap * svm = _Canvas->getSteerableViewMap();
618   if(!svm){
619     cerr << "the Steerable ViewMap has not been computed yet" << endl;
620     return;
621   }
622   svm->saveSteerableViewMap();
623 }
624
625 void Controller::toggleVisibilityAlgo() 
626 {
627   if(_VisibilityAlgo == ViewMapBuilder::ray_casting) {
628     _VisibilityAlgo = ViewMapBuilder::ray_casting_fast;
629   }
630   else if (_VisibilityAlgo == ViewMapBuilder::ray_casting_fast) {
631     _VisibilityAlgo = ViewMapBuilder::ray_casting_very_fast;
632   }
633   else {
634     _VisibilityAlgo = ViewMapBuilder::ray_casting;
635   }
636 }
637
638 void Controller::setQuantitativeInvisibility(bool iBool)
639 {
640   _EnableQI = iBool;
641 }
642
643 bool Controller::getQuantitativeInvisibility() const
644 {
645   return _EnableQI;
646 }
647
648 void Controller::setComputeRidgesAndValleysFlag(bool iBool){
649   _ComputeRidges = iBool;
650 }
651
652 bool Controller::getComputeRidgesAndValleysFlag() const {
653   return _ComputeRidges;
654 }
655
656 void Controller::setComputeSuggestiveContoursFlag(bool b){
657   _ComputeSuggestive = b;
658 }
659   
660 bool Controller::getComputeSuggestiveContoursFlag() const {
661   return _ComputeSuggestive;
662 }
663
664 void Controller::setComputeMaterialBoundariesFlag(bool b){
665   _ComputeMaterialBoundaries = b;
666 }
667   
668 bool Controller::getComputeMaterialBoundariesFlag() const {
669   return _ComputeMaterialBoundaries;
670 }
671
672 void Controller::setComputeSteerableViewMapFlag(bool iBool){
673   _ComputeSteerableViewMap = iBool;
674 }
675
676 bool Controller::getComputeSteerableViewMapFlag() const {
677   return _ComputeSteerableViewMap;
678 }
679
680 void Controller::DrawStrokes()
681 {
682   if(_ViewMap == 0)
683     return;
684
685   cout << "\n===  Stroke drawing  ===" << endl;
686   _Chrono.start();
687   _Canvas->Draw();
688   real d = _Chrono.stop();
689   cout << "Strokes generation  : " << d << endl;
690   cout << "Stroke count  : " << _Canvas->stroke_count << endl;
691   resetModified();
692 }
693
694 void Controller::ResetRenderCount()
695 {
696         _render_count = 0;
697 }
698
699 Render* Controller::RenderStrokes(Render *re) {
700         BlenderStrokeRenderer* blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count);
701         _Canvas->Render( blenderRenderer );
702         Render* freestyle_render = blenderRenderer->RenderScene(re);
703         delete blenderRenderer;
704         
705         return freestyle_render;
706 }
707
708 void Controller::InsertStyleModule(unsigned index, const char *iFileName)
709 {
710         if( !BLI_testextensie(iFileName, ".py") ) {
711                 cerr << "Error: Cannot load \"" << StringUtils::toAscii( string(iFileName) )
712                   << "\", unknown extension" << endl;
713                   return;
714         }
715
716   StyleModule* sm = new StyleModule(iFileName, _inter);
717   _Canvas->InsertStyleModule(index, sm);
718   
719 }
720
721 void Controller::InsertStyleModule(unsigned index, const char *iName, struct Text *iText)
722 {
723         StyleModule* sm = new BlenderStyleModule(iText, iName, _inter);
724   _Canvas->InsertStyleModule(index, sm);
725 }
726
727 void Controller::AddStyleModule(const char *iFileName)
728 {
729   //_pStyleWindow->Add(iFileName);
730 }
731
732 void Controller::RemoveStyleModule(unsigned index)
733 {
734   _Canvas->RemoveStyleModule(index);
735 }
736
737 void Controller::Clear()
738 {
739   _Canvas->Clear();
740 }
741
742 void Controller::ReloadStyleModule(unsigned index, const char * iFileName)
743 {
744   StyleModule* sm = new StyleModule(iFileName, _inter);
745   _Canvas->ReplaceStyleModule(index, sm);
746 }
747
748 void Controller::SwapStyleModules(unsigned i1, unsigned i2)
749 {
750   _Canvas->SwapStyleModules(i1, i2);
751 }
752
753
754 void Controller::toggleLayer(unsigned index, bool iDisplay)
755 {
756   _Canvas->setVisible(index, iDisplay);
757 }
758
759 void Controller::setModified(unsigned index, bool iMod)
760 {
761   //_pStyleWindow->setModified(index, iMod);
762   _Canvas->setModified(index, iMod);
763   updateCausalStyleModules(index + 1);
764 }
765
766 void Controller::updateCausalStyleModules(unsigned index) {
767   vector<unsigned> vec;
768   _Canvas->causalStyleModules(vec, index);
769   for (vector<unsigned>::const_iterator it = vec.begin(); it != vec.end(); it++) {
770     //_pStyleWindow->setModified(*it, true);
771     _Canvas->setModified(*it, true);
772   }
773 }
774
775 void Controller::resetModified(bool iMod)
776 {
777   //_pStyleWindow->resetModified(iMod);
778   _Canvas->resetModified(iMod);
779 }
780
781 NodeGroup * Controller::BuildRep(vector<ViewEdge*>::iterator vedges_begin, 
782                                        vector<ViewEdge*>::iterator vedges_end)
783 {
784   ViewMapTesselator2D tesselator2D;
785   FrsMaterial mat;
786   mat.setDiffuse(1,1,0.3,1);
787   tesselator2D.setFrsMaterial(mat);
788
789   return (tesselator2D.Tesselate(vedges_begin, vedges_end));
790 }
791
792 void Controller::toggleEdgeTesselationNature(Nature::EdgeNature iNature)
793 {
794   _edgeTesselationNature ^= (iNature);
795   ComputeViewMap();
796 }
797
798 void            Controller::setModelsDir(const string& dir) {
799   //_current_dirs->setValue("models/dir", dir);
800 }
801
802 string          Controller::getModelsDir() const {
803   string dir = ".";
804   //_current_dirs->getValue("models/dir", dir);
805   return dir;
806 }
807
808 void            Controller::setModulesDir(const string& dir) {
809   //_current_dirs->setValue("modules/dir", dir);
810 }
811
812 string          Controller::getModulesDir() const {
813   string dir = ".";
814   //_current_dirs->getValue("modules/dir", dir);
815   return dir;
816 }
817
818 void            Controller::setHelpIndex(const string& index) {
819   _help_index = index;
820 }
821
822 string          Controller::getHelpIndex() const {
823   return _help_index;
824 }
825
826 void            Controller::setBrowserCmd(const string& cmd) {
827   _browser_cmd = cmd;
828 }
829
830 string          Controller::getBrowserCmd() const {
831   return _browser_cmd;
832 }
833
834 void            Controller::resetInterpreter() {
835   if (_inter)
836     _inter->reset();
837 }
838
839
840 void Controller::displayDensityCurves(int x, int y){
841   SteerableViewMap * svm = _Canvas->getSteerableViewMap();
842   if(!svm)
843     return;
844
845   unsigned i,j;
846   typedef vector<Vec3r> densityCurve;
847   vector<densityCurve> curves(svm->getNumberOfOrientations()+1);
848   vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels());
849
850   // collect the curves values
851   unsigned nbCurves = svm->getNumberOfOrientations()+1;
852   unsigned nbPoints = svm->getNumberOfPyramidLevels();
853   if(!nbPoints)
854     return;
855
856   // build the density/nbLevels curves for each orientation
857   for(i=0;i<nbCurves; ++i){
858     for(j=0; j<nbPoints; ++j){
859       curves[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(i, j, x, y), 0));
860     }
861   }
862   // build the density/nbOrientations curves for each level
863   for(i=0;i<nbPoints; ++i){
864     for(j=0; j<nbCurves; ++j){
865       curvesDirection[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(j, i, x, y), 0));
866     }
867   }
868
869   // display the curves
870   // for(i=0; i<nbCurves; ++i)
871   //     _pDensityCurvesWindow->setOrientationCurve(i, Vec2d(0,0), Vec2d(nbPoints, 1), curves[i], "scale", "density");
872   //   for(i=1; i<=8; ++i)
873   //     _pDensityCurvesWindow->setLevelCurve(i, Vec2d(0,0), Vec2d(nbCurves, 1), curvesDirection[i], "orientation", "density");
874   //   _pDensityCurvesWindow->show();
875 }
876
877 void Controller::init_options(){
878 //      from AppOptionsWindow.cpp
879 //      Default init options
880
881         Config::Path * cpath = Config::Path::getInstance();
882         
883         // Directories
884         ViewMapIO::Options::setModelsPath( StringUtils::toAscii( cpath->getModelsPath() ) ); 
885         PythonInterpreter::Options::setPythonPath( StringUtils::toAscii( cpath->getPythonPath() ) );
886         TextureManager::Options::setPatternsPath( StringUtils::toAscii( cpath->getPatternsPath() ) );
887         TextureManager::Options::setBrushesPath( StringUtils::toAscii( cpath->getModelsPath() ) );
888
889         // ViewMap Format
890         ViewMapIO::Options::rmFlags(ViewMapIO::Options::FLOAT_VECTORS);
891         ViewMapIO::Options::rmFlags(ViewMapIO::Options::NO_OCCLUDERS);
892         setComputeSteerableViewMapFlag( false );
893
894         // Visibility
895         setQuantitativeInvisibility(true);
896
897         // soc: initialize canvas
898         _Canvas->init();
899
900         // soc: initialize passes
901         setPassDiffuse(NULL, 0, 0);
902         setPassZ(NULL, 0, 0);
903 }