Fixed a bug in SilhouetteGeomEngine::ImageToWorldParameter() that caused
[blender.git] / source / blender / freestyle / intern / blender_interface / FRS_freestyle.cpp
1 #include "../application/AppView.h"
2 #include "../application/Controller.h"
3 #include "../application/AppConfig.h"
4 #include "../application/AppCanvas.h"
5
6 #include <iostream>
7 #include <map>
8 #include <set>
9 using namespace std;
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
15 #include "MEM_guardedalloc.h"
16
17 #include "DNA_camera_types.h"
18 #include "DNA_freestyle_types.h"
19
20 #include "BKE_main.h"
21 #include "BLI_blenlib.h"
22 #include "BLI_math.h"
23 #include "BPY_extern.h"
24
25 #include "renderpipeline.h"
26 #include "pixelblending.h"
27
28 #include "../../FRS_freestyle.h"
29 #include "../../FRS_freestyle_config.h"
30
31         // Freestyle configuration
32         static short freestyle_is_initialized = 0;
33         static Config::Path *pathconfig = NULL;
34         static Controller *controller = NULL;
35         static AppView *view = NULL;
36
37         // camera information
38         float freestyle_viewpoint[3];
39         float freestyle_mv[4][4];
40         float freestyle_proj[4][4];
41         int freestyle_viewport[4];
42         
43         // current scene
44         Scene *freestyle_scene;
45
46         string default_module_path;
47
48         //=======================================================
49         //   Initialization 
50         //=======================================================
51
52         void FRS_initialize() {
53                 
54                 if( freestyle_is_initialized )
55                         return;
56
57                 pathconfig = new Config::Path;
58                 controller = new Controller();
59                 view = new AppView;
60                 controller->setView(view);
61                 freestyle_scene = NULL;
62                         
63                 default_module_path = pathconfig->getProjectDir() + Config::DIR_SEP + "style_modules" + Config::DIR_SEP + "contour.py";
64                         
65                 freestyle_is_initialized = 1;
66         }
67         
68         void FRS_set_context(bContext* C) {
69                 cout << "FRS_set_context: context 0x" << C << " scene 0x" << CTX_data_scene(C) << endl;
70                 controller->setContext(C);
71         }
72
73         void FRS_exit() {
74                 delete pathconfig;
75                 delete controller;
76                 delete view;
77         }
78
79         //=======================================================
80         //   Rendering 
81         //=======================================================
82
83         void init_view(Render* re){
84                 int width = re->scene->r.xsch;
85                 int height = re->scene->r.ysch;
86                 
87                 freestyle_viewport[0] = freestyle_viewport[1] = 0;
88                 freestyle_viewport[2] = width;
89                 freestyle_viewport[3] = height;
90                 
91                 view->setWidth( width );
92                 view->setHeight( height );
93         }
94
95         void init_camera(Render* re){
96                 Object* maincam_obj = re->scene->camera;
97                 // Camera *cam = (Camera*) maincam_obj->data;
98                 
99                 freestyle_viewpoint[0] = maincam_obj->obmat[3][0];
100                 freestyle_viewpoint[1] = maincam_obj->obmat[3][1];
101                 freestyle_viewpoint[2] = maincam_obj->obmat[3][2];
102                 
103                 for( int i = 0; i < 4; i++ )
104                    for( int j = 0; j < 4; j++ )
105                         freestyle_mv[i][j] = re->viewmat[i][j];
106                 
107                 for( int i = 0; i < 4; i++ )
108                    for( int j = 0; j < 4; j++ )
109                         freestyle_proj[i][j] = re->winmat[i][j];
110
111                 //print_m4("mv", freestyle_mv);
112                 //print_m4("proj", freestyle_proj);
113         }
114
115         
116         void prepare(Render* re, SceneRenderLayer* srl ) {
117                                 
118                 // clear canvas
119                 controller->Clear();
120
121                 // load mesh
122                 if( controller->LoadMesh(re, srl) ) // returns if scene cannot be loaded or if empty
123                         return;
124                 
125                 // add style modules
126                 FreestyleConfig* config = &srl->freestyleConfig;
127                 
128                 cout << "\n===  Rendering options  ===" << endl;
129                 cout << "Modules :"<< endl;
130                 int layer_count = 0;
131                 
132
133                 for( FreestyleModuleConfig* module_conf = (FreestyleModuleConfig *)config->modules.first; module_conf; module_conf = module_conf->next ) {
134                         if( module_conf->is_displayed ) {
135                                 cout << "  " << layer_count+1 << ": " << module_conf->module_path << endl;
136                                 controller->InsertStyleModule( layer_count, module_conf->module_path );
137                                 controller->toggleLayer(layer_count, true);
138                                 layer_count++;
139                         }
140                 }       
141                 cout << endl;
142                 
143                 // set parameters
144                 controller->setSphereRadius( config->sphere_radius );
145                 controller->setComputeRidgesAndValleysFlag( (config->flags & FREESTYLE_RIDGES_AND_VALLEYS_FLAG) ? true : false);
146                 controller->setComputeSuggestiveContoursFlag( (config->flags & FREESTYLE_SUGGESTIVE_CONTOURS_FLAG) ? true : false);
147                 controller->setSuggestiveContourKrDerivativeEpsilon( config->dkr_epsilon ) ;
148
149                 cout << "Sphere radius : " << controller->getSphereRadius() << endl;
150                 cout << "Redges and valleys : " << (controller->getComputeRidgesAndValleysFlag() ? "enabled" : "disabled") << endl;
151                 cout << "Suggestive contours : " << (controller->getComputeSuggestiveContoursFlag() ? "enabled" : "disabled") << endl;
152                 cout << "Suggestive contour dkr epsilon : " << controller->getSuggestiveContourKrDerivativeEpsilon() << endl;
153
154                 // compute view map
155                 controller->ComputeViewMap();
156         }
157         
158         void composite_result(Render* re, SceneRenderLayer* srl, Render* freestyle_render)
159         {
160
161                 RenderLayer *rl;
162             float *src, *dest, *pixSrc, *pixDest;
163                 int x, y, rectx, recty;
164                 
165                 if( freestyle_render == NULL || freestyle_render->result == NULL )
166                         return;
167
168                 rl = render_get_active_layer( freestyle_render, freestyle_render->result );
169             if( !rl || rl->rectf == NULL) { cout << "Cannot find Freestyle result image" << endl; return; }
170                 src  = rl->rectf;
171                 
172                 rl = RE_GetRenderLayer(re->result, srl->name);
173             if( !rl || rl->rectf == NULL) { cout << "No layer to composite to" << endl; return; }
174                 dest  = rl->rectf;
175                 
176                 rectx = re->rectx;
177                 recty = re->recty;
178
179             for( y = 0; y < recty; y++) {
180                 for( x = 0; x < rectx; x++) {
181
182                     pixSrc = src + 4 * (rectx * y + x);
183                     if( pixSrc[3] > 0.0) {
184                                         pixDest = dest + 4 * (rectx * y + x);
185                                         addAlphaOverFloat(pixDest, pixSrc);
186                      }
187                  }
188             }
189                 
190         }
191         
192         int displayed_layer_count( SceneRenderLayer* srl ) {
193                 int count = 0;
194
195                 for( FreestyleModuleConfig* module_conf = (FreestyleModuleConfig *)srl->freestyleConfig.modules.first; module_conf; module_conf = module_conf->next ) {
196                         if( module_conf->is_displayed )
197                                 count++;
198                 }
199                 return count;
200         }
201         
202         void FRS_add_Freestyle(Render* re) {
203                 
204                 SceneRenderLayer *srl;
205                 Render* freestyle_render = NULL;
206                 
207                 // init
208                 cout << "\n#===============================================================" << endl;
209                 cout << "#  Freestyle" << endl;
210                 cout << "#===============================================================" << endl;
211                 
212                 init_view(re);
213                 init_camera(re);
214                 freestyle_scene = re->scene;
215                 
216                 for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) {
217                         if( !(srl->layflag & SCE_LAY_DISABLE) &&
218                                 srl->layflag & SCE_LAY_FRS &&
219                                 displayed_layer_count(srl) > 0       )
220                         {
221                                 cout << "\n----------------------------------------------------------" << endl;
222                                 cout << "|  " << (re->scene->id.name+2) << "|" << srl->name << endl;
223                                 cout << "----------------------------------------------------------" << endl;
224                                 
225                                 // prepare Freestyle:
226                                 //   - clear canvas
227                                 //   - load mesh
228                                 //   - add style modules
229                                 //   - set parameters
230                                 //   - compute view map
231                                 prepare(re, srl);
232
233                                 // render and composite Freestyle result
234                                 if( controller->_ViewMap ) {
235                                         
236                                         // render strokes                                       
237                                         controller->DrawStrokes();
238                                         freestyle_render = controller->RenderStrokes(re);
239                                         controller->CloseFile();
240                                         
241                                         // composite result
242                                         composite_result(re, srl, freestyle_render);
243                                         
244                                         // free resources
245                                         RE_FreeRender(freestyle_render);
246                                 }
247                         }
248                 }
249                 
250                 freestyle_scene = NULL;
251         }
252
253         //=======================================================
254         //   Freestyle Panel Configuration
255         //=======================================================
256
257         void FRS_add_freestyle_config( SceneRenderLayer* srl )
258         {               
259                 FreestyleConfig* config = &srl->freestyleConfig;
260                 
261                 config->modules.first = config->modules.last = NULL;
262                 config->flags = 0;
263                 config->sphere_radius = 1.0;
264                 config->dkr_epsilon = 0.001;
265         }
266         
267         void FRS_free_freestyle_config( SceneRenderLayer* srl )
268         {               
269                 BLI_freelistN( &srl->freestyleConfig.modules );
270         }
271
272         void FRS_add_module(FreestyleConfig *config)
273         {
274                 FreestyleModuleConfig* module_conf = (FreestyleModuleConfig*) MEM_callocN( sizeof(FreestyleModuleConfig), "style module configuration");
275                 BLI_addtail(&config->modules, (void*) module_conf);
276                 
277                 strcpy( module_conf->module_path, default_module_path.c_str() );
278                 module_conf->is_displayed = 1;  
279         }
280         
281         void FRS_delete_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf)
282         {
283                 BLI_freelinkN(&config->modules, module_conf);
284         }
285         
286         void FRS_move_up_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf)
287         {
288                 BLI_remlink(&config->modules, module_conf);
289                 BLI_insertlink(&config->modules, module_conf->prev->prev, module_conf);
290         }
291         
292         void FRS_move_down_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf)
293         {                       
294                 BLI_remlink(&config->modules, module_conf);
295                 BLI_insertlink(&config->modules, module_conf->next, module_conf);
296         }
297
298 #ifdef __cplusplus
299 }
300 #endif