Made minor revisions (no functional changes).
[blender.git] / source / blender / freestyle / intern / blender_interface / BlenderStrokeRenderer.cpp
1 # include "BlenderStrokeRenderer.h"
2 # include "../stroke/Canvas.h"
3 # include "../application/AppConfig.h"
4
5 # include "BlenderTextureManager.h"
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11 #include "MEM_guardedalloc.h"
12
13 #include "DNA_camera_types.h"
14 #include "DNA_customdata_types.h"
15 #include "DNA_listBase.h"
16 #include "DNA_mesh_types.h"
17 #include "DNA_meshdata_types.h"
18 #include "DNA_object_types.h"
19 #include "DNA_screen_types.h"
20
21 #include "BKE_customdata.h"
22 #include "BKE_global.h"
23 #include "BKE_library.h" /* free_libblock */
24 #include "BKE_material.h"
25 #include "BKE_main.h" /* struct Main */
26 #include "BKE_object.h"
27 #include "BKE_scene.h"
28
29 #include "RE_pipeline.h"
30
31 #ifdef __cplusplus
32 }
33 #endif
34
35
36 BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re, int render_count)
37 :StrokeRenderer(){
38         
39         // TEMPORARY - need a  texture manager
40         _textureManager = new BlenderTextureManager;
41         _textureManager->load();
42
43         _width = re->winx; _height = re->winy; // for stroke mesh generation
44
45         // Scene.New("FreestyleStrokes")
46         old_scene = re->scene;
47
48         char name[22];
49         snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name+2);
50         freestyle_scene = add_scene(name);
51         freestyle_scene->r.cfra = old_scene->r.cfra;
52         freestyle_scene->r.mode= old_scene->r.mode &
53                 ~( R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER );
54         freestyle_scene->r.xsch= re->rectx; // old_scene->r.xsch
55         freestyle_scene->r.ysch= re->recty; // old_scene->r.ysch
56         freestyle_scene->r.xasp= old_scene->r.xasp;
57         freestyle_scene->r.yasp= old_scene->r.yasp;
58         freestyle_scene->r.xparts= old_scene->r.xparts;
59         freestyle_scene->r.yparts= old_scene->r.yparts;
60         freestyle_scene->r.size= 100; // old_scene->r.size
61         freestyle_scene->r.maximsize= old_scene->r.maximsize;
62         freestyle_scene->r.ocres = old_scene->r.ocres;
63         freestyle_scene->r.color_mgt_flag = old_scene->r.color_mgt_flag;
64         freestyle_scene->r.scemode= old_scene->r.scemode & ~( R_SINGLE_LAYER );
65         freestyle_scene->r.flag= old_scene->r.flag;
66         freestyle_scene->r.threads= old_scene->r.threads;
67         freestyle_scene->r.border.xmin= old_scene->r.border.xmin;
68         freestyle_scene->r.border.ymin= old_scene->r.border.ymin;
69         freestyle_scene->r.border.xmax= old_scene->r.border.xmax;
70         freestyle_scene->r.border.ymax= old_scene->r.border.ymax;
71         strcpy(freestyle_scene->r.pic, old_scene->r.pic);
72         freestyle_scene->r.safety.xmin= old_scene->r.safety.xmin;
73         freestyle_scene->r.safety.ymin= old_scene->r.safety.ymin;
74         freestyle_scene->r.safety.xmax= old_scene->r.safety.xmax;
75         freestyle_scene->r.safety.ymax= old_scene->r.safety.ymax;
76         freestyle_scene->r.osa= old_scene->r.osa;
77         freestyle_scene->r.filtertype= old_scene->r.filtertype;
78         freestyle_scene->r.gauss= old_scene->r.gauss;
79         freestyle_scene->r.dither_intensity= old_scene->r.dither_intensity;
80         BLI_strncpy(freestyle_scene->r.engine, old_scene->r.engine, sizeof(freestyle_scene->r.engine));
81         freestyle_scene->r.planes = R_PLANES32;
82         freestyle_scene->r.imtype = R_PNG;
83         set_scene_bg( G.main, freestyle_scene );
84
85         // Camera
86         Object* object_camera = add_object(freestyle_scene, OB_CAMERA);
87         
88         Camera* camera = (Camera *) object_camera->data;
89         camera->type = CAM_ORTHO;
90         camera->ortho_scale = max(re->rectx, re->recty);
91     camera->clipsta = 0.1f;
92     camera->clipend = 100.0f;
93
94     _z_delta = 0.00001f;
95     _z = camera->clipsta + _z_delta;
96
97     // test
98     //_z = 999.90f; _z_delta = 0.01f;
99
100         object_camera->loc[0] = re->disprect.xmin + 0.5f * re->rectx;
101         object_camera->loc[1] = re->disprect.ymin + 0.5f * re->recty;
102         object_camera->loc[2] = 1.f;
103         
104         freestyle_scene->camera = object_camera;
105         
106         // Material
107         material = add_material("stroke_material");
108         material->mode |= MA_VERTEXCOLP;
109         material->mode |= MA_TRANSP;
110         material->mode |= MA_SHLESS;
111         material->vcol_alpha = 1;
112 }
113
114 BlenderStrokeRenderer::~BlenderStrokeRenderer(){
115         
116         if(0 != _textureManager)
117         {
118                 delete _textureManager;
119                 _textureManager = 0;
120         }
121
122         // The freestyle_scene object is not released here.  Instead,
123         // the scene is released in free_all_freestyle_renders() in
124         // source/blender/render/intern/source/pipeline.c, after the
125         // compositor has finished.
126
127         // release objects and data blocks
128         Base *b = (Base *)freestyle_scene->base.first;
129         while(b) {
130                 Object *ob = b->object;
131                 void *data = ob->data;
132                 char name[24];
133                 strcpy(name, ob->id.name);
134                 //cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl;
135                 switch (ob->type) {
136                 case OB_MESH:
137                         free_libblock( &G.main->object, ob );
138                         free_libblock( &G.main->mesh, data );
139                         break;
140                 case OB_CAMERA:
141                         free_libblock( &G.main->object, ob );
142                         free_libblock( &G.main->camera, data );
143                         freestyle_scene->camera = NULL;
144                         break;
145                 default:
146                         cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name+2) << endl;
147                 }
148                 b = b->next;
149         }
150         BLI_freelistN( &freestyle_scene->base );
151
152         // release material
153         free_libblock( &G.main->mat, material );
154         
155         set_scene_bg( G.main, old_scene );
156 }
157
158 float BlenderStrokeRenderer::get_stroke_vertex_z(void) const {
159     float z = _z;
160     BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
161     if (!(_z < _z_delta * 100000.0f))
162         self->_z_delta *= 10.0f;
163     self->_z += _z_delta;
164     return -z;
165 }
166
167 void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const{
168   RenderStrokeRepBasic(iStrokeRep);
169 }
170
171 void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{
172         
173         ////////////////////
174         //  Build up scene
175         ////////////////////
176         
177           vector<Strip*>& strips = iStrokeRep->getStrips();
178           Strip::vertex_container::iterator v[3];
179           StrokeVertexRep *svRep[3];
180           Vec3r color[3];
181           unsigned int vertex_index;
182           Vec2r p;
183         
184           for(vector<Strip*>::iterator s=strips.begin(), send=strips.end();
185           s!=send;
186           ++s){         
187                 
188             Strip::vertex_container& strip_vertices = (*s)->vertices();
189                 int strip_vertex_count = (*s)->sizeStrip();
190                 int m, n, visible_faces, visible_segments;
191                 bool visible;
192
193                 // iterate over all vertices and count visible faces and strip segments
194                 // (note: a strip segment is a series of visible faces, while two strip
195                 // segments are separated by one or more invisible faces)
196                 v[0] = strip_vertices.begin();
197             v[1] = v[0]; ++(v[1]);
198             v[2] = v[1]; ++(v[2]);
199                 visible_faces = visible_segments = 0;
200                 visible = false;
201             for (n = 2; n < strip_vertex_count; n++)
202                 {
203                         svRep[0] = *(v[0]);
204                         svRep[1] = *(v[1]);
205                         svRep[2] = *(v[2]);
206                         m = 0;
207                         for (int j = 0; j < 3; j++) {
208                                 p = svRep[j]->point2d();
209                                 if (p[0] < 0.0 || p[0] > _width || p[1] < 0.0 || p[1] > _height)
210                                         m++;
211                         }
212                         if (m == 3) {
213                                 visible = false;
214                         } else {
215                                 visible_faces++;
216                                 if (!visible)
217                                         visible_segments++;
218                                 visible = true;
219                         }
220                         ++v[0]; ++v[1]; ++v[2];
221                 }
222                 if (visible_faces == 0)
223                         continue;
224
225                 // me = Mesh.New()
226                 Object* object_mesh = add_object(freestyle_scene, OB_MESH);
227                 Mesh* mesh = (Mesh *) object_mesh->data;
228                 MEM_freeN(mesh->bb);
229                 mesh->bb= NULL;
230                 mesh->id.us = 0;
231                 
232 #if 1
233                 // me.materials = [mat]
234                 mesh->mat = ( Material ** ) MEM_mallocN( 1 * sizeof( Material * ), "MaterialList" );
235                 mesh->mat[0] = material;
236                 mesh->totcol = 1;
237                 test_object_materials( (ID*) mesh );
238 #else
239                 assign_material(object_mesh, material, object_mesh->totcol+1);
240                 object_mesh->actcol= object_mesh->totcol;
241 #endif
242                 
243                 // vertices allocation
244                 mesh->totvert = visible_faces + visible_segments * 2;
245                 mesh->mvert = (MVert*) CustomData_add_layer( &mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
246                         
247                 // faces allocation
248                 mesh->totface = visible_faces;
249                 mesh->mface = (MFace*) CustomData_add_layer( &mesh->fdata, CD_MFACE, CD_CALLOC, NULL, mesh->totface);
250                 
251                 // colors allocation  - me.vertexColors = True
252                 mesh->mcol = (MCol *) CustomData_add_layer( &mesh->fdata, CD_MCOL, CD_CALLOC, NULL, mesh->totface );
253
254                 ////////////////////
255                 //  Data copy
256                 ////////////////////
257                 
258                 MVert* vertices = mesh->mvert;
259                 MFace* faces = mesh->mface;
260                 MCol* colors = mesh->mcol;
261                 
262             v[0] = strip_vertices.begin();
263             v[1] = v[0]; ++(v[1]);
264             v[2] = v[1]; ++(v[2]);
265
266                 vertex_index = 0;
267                 visible = false;
268                 
269             for (n = 2; n < strip_vertex_count; n++)
270                 {
271                         svRep[0] = *(v[0]);
272                         svRep[1] = *(v[1]);
273                         svRep[2] = *(v[2]);
274                         m = 0;
275                         for (int j = 0; j < 3; j++) {
276                                 p = svRep[j]->point2d();
277                                 if (p[0] < 0.0 || p[0] > _width || p[1] < 0.0 || p[1] > _height)
278                                         m++;
279                         }
280                         if (m == 3) {
281                                 visible = false;
282                         } else {
283                                 if (!visible) {
284                                         vertex_index += 2;
285
286                                         // first vertex
287                                         vertices->co[0] = svRep[0]->point2d()[0];
288                                         vertices->co[1] = svRep[0]->point2d()[1];
289                                         vertices->co[2] = get_stroke_vertex_z();
290                                         ++vertices;
291                                         
292                                         // second vertex
293                                         vertices->co[0] = svRep[1]->point2d()[0];
294                                         vertices->co[1] = svRep[1]->point2d()[1];
295                                         vertices->co[2] = get_stroke_vertex_z();
296                                         ++vertices;
297                                 }
298                                 visible = true;
299
300                                 // vertex
301                                 vertices->co[0] = svRep[2]->point2d()[0];
302                                 vertices->co[1] = svRep[2]->point2d()[1];
303                                 vertices->co[2] = get_stroke_vertex_z();
304                                 
305                                 // faces
306                                 faces->v1 = vertex_index - 2;
307                                 faces->v2 = vertex_index - 1;
308                                 faces->v3 = vertex_index;
309                                 faces->v4 = 0;
310                                 
311                                 // colors
312                                 // red and blue are swapped - cf DNA_meshdata_types.h : MCol    
313                                 color[0] = svRep[0]->color();
314                                 color[1] = svRep[1]->color();
315                                 color[2] = svRep[2]->color();
316
317                                 colors->r = (short)(255.0f*(color[0])[2]);
318                                 colors->g = (short)(255.0f*(color[0])[1]);
319                                 colors->b = (short)(255.0f*(color[0])[0]);
320                                 colors->a = (short)(255.0f*svRep[0]->alpha());
321                                 ++colors;
322                                 
323                                 colors->r = (short)(255.0f*(color[1])[2]);
324                                 colors->g = (short)(255.0f*(color[1])[1]);
325                                 colors->b = (short)(255.0f*(color[1])[0]);
326                                 colors->a = (short)(255.0f*svRep[1]->alpha());
327                                 ++colors;
328                                 
329                                 colors->r = (short)(255.0f*(color[2])[2]);
330                                 colors->g = (short)(255.0f*(color[2])[1]);
331                                 colors->b = (short)(255.0f*(color[2])[0]);
332                                 colors->a = (short)(255.0f*svRep[2]->alpha());
333                                 ++colors;
334
335                                 ++faces; ++vertices; ++colors;
336                                 ++vertex_index;
337                         }
338                         ++v[0]; ++v[1]; ++v[2];
339
340                 } // loop over strip vertices 
341         
342         } // loop over strips   
343
344 }
345
346 Render* BlenderStrokeRenderer::RenderScene( Render *re ) {
347     Camera *camera = (Camera *)freestyle_scene->camera->data;
348     if (camera->clipend < _z)
349         camera->clipend = _z + _z_delta * 100.0f;
350     //cout << "clipsta " << camera->clipsta << ", clipend " << camera->clipend << endl;
351
352         Render *freestyle_render = RE_NewRender(freestyle_scene->id.name);
353
354         RE_RenderFreestyleStrokes(freestyle_render, G.main, freestyle_scene);
355         return freestyle_render;
356 }