Freestyle changes:
[blender-staging.git] / source / blender / freestyle / intern / blender_interface / BlenderStrokeRenderer.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2010 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
29  *  \ingroup freestyle
30  */
31
32 #include "BlenderStrokeRenderer.h"
33 #include "BlenderTextureManager.h"
34
35 #include "../application/AppConfig.h"
36 #include "../stroke/Canvas.h"
37
38 #include "BKE_global.h"
39
40 // XXX Are those "ifdef __cplusplus" useful here?
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 #include "MEM_guardedalloc.h"
46
47 #include "DNA_camera_types.h"
48 #include "DNA_customdata_types.h"
49 #include "DNA_listBase.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_mesh_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_screen_types.h"
54
55 #include "BKE_customdata.h"
56 #include "BKE_global.h"
57 #include "BKE_library.h" /* free_libblock */
58 #include "BKE_main.h" /* struct Main */
59 #include "BKE_material.h"
60 #include "BKE_mesh.h"
61 #include "BKE_object.h"
62 #include "BKE_scene.h"
63
64 #include "RE_pipeline.h"
65
66 #ifdef __cplusplus
67 }
68 #endif
69
70 BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
71 {
72         // TEMPORARY - need a  texture manager
73         _textureManager = new BlenderTextureManager;
74         _textureManager->load();
75
76         // for stroke mesh generation
77         _width = re->winx;
78         _height = re->winy;
79
80         //Scene.New("FreestyleStrokes")
81         old_scene = re->scene;
82
83         char name[22];
84         BLI_snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name + 2);
85         freestyle_scene = BKE_scene_add(G.main, name);
86         freestyle_scene->r.cfra = old_scene->r.cfra;
87         freestyle_scene->r.mode = old_scene->r.mode &
88                                   ~(R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER);
89         freestyle_scene->r.xsch = re->rectx; // old_scene->r.xsch
90         freestyle_scene->r.ysch = re->recty; // old_scene->r.ysch
91         freestyle_scene->r.xasp = 1.0f; // old_scene->r.xasp;
92         freestyle_scene->r.yasp = 1.0f; // old_scene->r.yasp;
93         freestyle_scene->r.tilex = old_scene->r.tilex;
94         freestyle_scene->r.tiley = old_scene->r.tiley;
95         freestyle_scene->r.size = 100; // old_scene->r.size
96         //freestyle_scene->r.maximsize = old_scene->r.maximsize; /* DEPRECATED */
97         freestyle_scene->r.ocres = old_scene->r.ocres;
98         freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag;
99         freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER);
100         freestyle_scene->r.flag = old_scene->r.flag;
101         freestyle_scene->r.threads = old_scene->r.threads;
102         freestyle_scene->r.border.xmin = old_scene->r.border.xmin;
103         freestyle_scene->r.border.ymin = old_scene->r.border.ymin;
104         freestyle_scene->r.border.xmax = old_scene->r.border.xmax;
105         freestyle_scene->r.border.ymax = old_scene->r.border.ymax;
106         strcpy(freestyle_scene->r.pic, old_scene->r.pic);
107         freestyle_scene->r.safety.xmin = old_scene->r.safety.xmin;
108         freestyle_scene->r.safety.ymin = old_scene->r.safety.ymin;
109         freestyle_scene->r.safety.xmax = old_scene->r.safety.xmax;
110         freestyle_scene->r.safety.ymax = old_scene->r.safety.ymax;
111         freestyle_scene->r.osa = old_scene->r.osa;
112         freestyle_scene->r.filtertype = old_scene->r.filtertype;
113         freestyle_scene->r.gauss = old_scene->r.gauss;
114         freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity;
115         BLI_strncpy(freestyle_scene->r.engine, old_scene->r.engine, sizeof(freestyle_scene->r.engine));
116         freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA; 
117         freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG;
118         BKE_scene_disable_color_management(freestyle_scene);
119
120         if (G.debug & G_DEBUG_FREESTYLE) {
121                 printf("%s: %d threads\n", __func__, freestyle_scene->r.threads);
122         }
123
124         // Render layer
125         SceneRenderLayer *srl = (SceneRenderLayer *)freestyle_scene->r.layers.first;
126         srl->layflag = SCE_LAY_SOLID | SCE_LAY_ZTRA;
127
128         BKE_scene_set_background(G.main, freestyle_scene);
129
130         // Camera
131         Object *object_camera = BKE_object_add(freestyle_scene, OB_CAMERA);
132
133         Camera *camera = (Camera *)object_camera->data;
134         camera->type = CAM_ORTHO;
135         camera->ortho_scale = max(re->rectx, re->recty);
136         camera->clipsta = 0.1f;
137         camera->clipend = 100.0f;
138
139         _z_delta = 0.00001f;
140         _z = camera->clipsta + _z_delta;
141
142         // test
143         //_z = 999.90f; _z_delta = 0.01f;
144
145         object_camera->loc[0] = re->disprect.xmin + 0.5f * re->rectx;
146         object_camera->loc[1] = re->disprect.ymin + 0.5f * re->recty;
147         object_camera->loc[2] = 1.0f;
148
149         freestyle_scene->camera = object_camera;
150
151         // Material
152         material = BKE_material_add(G.main, "stroke_material");
153         material->mode |= MA_VERTEXCOLP;
154         material->mode |= MA_TRANSP;
155         material->mode |= MA_SHLESS;
156         material->vcol_alpha = 1;
157
158         // Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh())
159         _mesh_id = 0xffffffff;
160 }
161
162 BlenderStrokeRenderer::~BlenderStrokeRenderer()
163 {
164         if (0 != _textureManager) {
165                 delete _textureManager;
166                 _textureManager = NULL;
167         }
168
169         // The freestyle_scene object is not released here.  Instead,
170         // the scene is released in free_all_freestyle_renders() in
171         // source/blender/render/intern/source/pipeline.c, after the
172         // compositor has finished.
173
174         // release objects and data blocks
175         for (Base *b = (Base *)freestyle_scene->base.first; b; b = b->next) {
176                 Object *ob = b->object;
177                 void *data = ob->data;
178                 char *name = ob->id.name;
179 #if 0
180                 if (G.debug & G_DEBUG_FREESTYLE) {
181                         cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl;
182                 }
183 #endif
184                 switch (ob->type) {
185                 case OB_MESH:
186                         BKE_libblock_free(&G.main->object, ob);
187                         BKE_libblock_free(&G.main->mesh, data);
188                         break;
189                 case OB_CAMERA:
190                         BKE_libblock_free(&G.main->object, ob);
191                         BKE_libblock_free(&G.main->camera, data);
192                         freestyle_scene->camera = NULL;
193                         break;
194                 default:
195                         cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name + 2) << endl;
196                 }
197         }
198         BLI_freelistN(&freestyle_scene->base);
199
200         // release material
201         BKE_libblock_free(&G.main->mat, material);
202
203         BKE_scene_set_background(G.main, old_scene);
204 }
205
206 float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
207 {
208         float z = _z;
209         BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
210         if (!(_z < _z_delta * 100000.0f))
211                 self->_z_delta *= 10.0f;
212         self->_z += _z_delta;
213         return -z;
214 }
215
216 unsigned int BlenderStrokeRenderer::get_stroke_mesh_id(void) const
217 {
218         unsigned mesh_id = _mesh_id;
219         BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
220         self->_mesh_id--;
221         return mesh_id;
222 }
223
224 void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
225 {
226         RenderStrokeRepBasic(iStrokeRep);
227 }
228
229 void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
230 {
231         ////////////////////
232         //  Build up scene
233         ////////////////////
234
235         vector<Strip*>& strips = iStrokeRep->getStrips();
236         Strip::vertex_container::iterator v[3];
237         StrokeVertexRep *svRep[3];
238         /* Vec3r color[3]; */ /* UNUSED */
239         unsigned int vertex_index, edge_index, loop_index;
240         Vec2r p;
241
242         for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
243                 Strip::vertex_container& strip_vertices = (*s)->vertices();
244                 int strip_vertex_count = (*s)->sizeStrip();
245                 int xl, xu, yl, yu, n, visible_faces, visible_segments;
246                 bool visible;
247
248                 // iterate over all vertices and count visible faces and strip segments
249                 // (note: a strip segment is a series of visible faces, while two strip
250                 // segments are separated by one or more invisible faces)
251                 v[0] = strip_vertices.begin();
252                 v[1] = v[0] + 1;
253                 v[2] = v[0] + 2;
254                 visible_faces = visible_segments = 0;
255                 visible = false;
256                 for (n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
257                         svRep[0] = *(v[0]);
258                         svRep[1] = *(v[1]);
259                         svRep[2] = *(v[2]);
260                         xl = xu = yl = yu = 0;
261                         for (int j = 0; j < 3; j++) {
262                                 p = svRep[j]->point2d();
263                                 if (p[0] < 0.0)
264                                         xl++;
265                                 else if (p[0] > _width)
266                                         xu++;
267                                 if (p[1] < 0.0)
268                                         yl++;
269                                 else if (p[1] > _height)
270                                         yu++;
271                         }
272                         if (xl == 3 || xu == 3 || yl == 3 || yu == 3) {
273                                 visible = false;
274                         }
275                         else {
276                                 visible_faces++;
277                                 if (!visible)
278                                         visible_segments++;
279                                 visible = true;
280                         }
281                 }
282                 if (visible_faces == 0)
283                         continue;
284
285                 //me = Mesh.New()
286 #if 0
287                 Object *object_mesh = BKE_object_add(freestyle_scene, OB_MESH);
288 #else
289                 Object *object_mesh = NewMesh();
290 #endif
291                 Mesh *mesh = (Mesh *)object_mesh->data;
292 #if 0
293                 MEM_freeN(mesh->bb);
294                 mesh->bb = NULL;
295                 mesh->id.us = 0;
296 #endif
297 #if 1
298                 //me.materials = [mat]
299                 mesh->mat = (Material **)MEM_mallocN(1 * sizeof(Material *), "MaterialList");
300                 mesh->mat[0] = material;
301                 mesh->totcol = 1;
302                 test_object_materials((ID *)mesh);
303 #else
304                 assign_material(object_mesh, material, object_mesh->totcol + 1);
305                 object_mesh->actcol = object_mesh->totcol;
306 #endif
307
308                 // vertices allocation
309                 mesh->totvert = visible_faces + visible_segments * 2;
310                 mesh->mvert = (MVert *)CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
311
312                 // edges allocation
313                 mesh->totedge = visible_faces * 2 + visible_segments;
314                 mesh->medge = (MEdge *)CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
315
316                 // faces allocation
317                 mesh->totpoly = visible_faces;
318                 mesh->mpoly = (MPoly *)CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
319
320                 // loops allocation
321                 mesh->totloop = visible_faces * 3;
322                 mesh->mloop = (MLoop *)CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
323
324                 // colors allocation
325                 mesh->mloopcol = (MLoopCol *)CustomData_add_layer(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop);
326
327                 ////////////////////
328                 //  Data copy
329                 ////////////////////
330
331                 MVert *vertices = mesh->mvert;
332                 MEdge *edges = mesh->medge;
333                 MPoly *polys = mesh->mpoly;
334                 MLoop *loops = mesh->mloop;
335                 MLoopCol *colors = mesh->mloopcol;
336
337                 v[0] = strip_vertices.begin();
338                 v[1] = v[0] + 1;
339                 v[2] = v[0] + 2;
340
341                 vertex_index = edge_index = loop_index = 0;
342                 visible = false;
343
344                 // Note: Mesh generation in the following loop assumes stroke strips
345                 // to be triangle strips.
346                 for (n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
347                         svRep[0] = *(v[0]);
348                         svRep[1] = *(v[1]);
349                         svRep[2] = *(v[2]);
350                         xl = xu = yl = yu = 0;
351                         for (int j = 0; j < 3; j++) {
352                                 p = svRep[j]->point2d();
353                                 if (p[0] < 0.0)
354                                         xl++;
355                                 else if (p[0] > _width)
356                                         xu++;
357                                 if (p[1] < 0.0)
358                                         yl++;
359                                 else if (p[1] > _height)
360                                         yu++;
361                         }
362                         if (xl == 3 || xu == 3 || yl == 3 || yu == 3) {
363                                 visible = false;
364                         }
365                         else {
366                                 if (!visible) {
367                                         // first vertex
368                                         vertices->co[0] = svRep[0]->point2d()[0];
369                                         vertices->co[1] = svRep[0]->point2d()[1];
370                                         vertices->co[2] = get_stroke_vertex_z();
371                                         ++vertices;
372                                         ++vertex_index;
373
374                                         // second vertex
375                                         vertices->co[0] = svRep[1]->point2d()[0];
376                                         vertices->co[1] = svRep[1]->point2d()[1];
377                                         vertices->co[2] = get_stroke_vertex_z();
378                                         ++vertices;
379                                         ++vertex_index;
380
381                                         // first edge
382                                         edges->v1 = vertex_index - 2;
383                                         edges->v2 = vertex_index - 1;
384                                         ++edges;
385                                         ++edge_index;
386                                 }
387                                 visible = true;
388
389                                 // vertex
390                                 vertices->co[0] = svRep[2]->point2d()[0];
391                                 vertices->co[1] = svRep[2]->point2d()[1];
392                                 vertices->co[2] = get_stroke_vertex_z();
393                                 ++vertices;
394                                 ++vertex_index;
395
396                                 // edges
397                                 edges->v1 = vertex_index - 1;
398                                 edges->v2 = vertex_index - 3;
399                                 ++edges;
400                                 ++edge_index;
401
402                                 edges->v1 = vertex_index - 1;
403                                 edges->v2 = vertex_index - 2;
404                                 ++edges;
405                                 ++edge_index;
406
407                                 // poly
408                                 polys->loopstart = loop_index;
409                                 polys->totloop = 3;
410                                 ++polys;
411
412                                 // loops
413                                 if (n % 2 == 0) {
414                                         loops[0].v = vertex_index - 1;
415                                         loops[0].e = edge_index - 1;
416
417                                         loops[1].v = vertex_index - 2;
418                                         loops[1].e = edge_index - 3;
419
420                                         loops[2].v = vertex_index - 3;
421                                         loops[2].e = edge_index - 2;
422                                 }
423                                 else {
424                                         loops[0].v = vertex_index - 1;
425                                         loops[0].e = edge_index - 2;
426
427                                         loops[1].v = vertex_index - 3;
428                                         loops[1].e = edge_index - 3;
429
430                                         loops[2].v = vertex_index - 2;
431                                         loops[2].e = edge_index - 1;
432                                 }
433                                 loops += 3;
434                                 loop_index += 3;
435
436                                 // colors
437                                 if (n % 2 == 0) {
438                                         colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
439                                         colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
440                                         colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
441                                         colors[0].a = (short)(255.0f * svRep[2]->alpha());
442
443                                         colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
444                                         colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
445                                         colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
446                                         colors[1].a = (short)(255.0f * svRep[1]->alpha());
447
448                                         colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
449                                         colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
450                                         colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
451                                         colors[2].a = (short)(255.0f * svRep[0]->alpha());
452                                 }
453                                 else {
454                                         colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
455                                         colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
456                                         colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
457                                         colors[0].a = (short)(255.0f * svRep[2]->alpha());
458
459                                         colors[1].r = (short)(255.0f * svRep[0]->color()[0]);
460                                         colors[1].g = (short)(255.0f * svRep[0]->color()[1]);
461                                         colors[1].b = (short)(255.0f * svRep[0]->color()[2]);
462                                         colors[1].a = (short)(255.0f * svRep[0]->alpha());
463
464                                         colors[2].r = (short)(255.0f * svRep[1]->color()[0]);
465                                         colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
466                                         colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
467                                         colors[2].a = (short)(255.0f * svRep[1]->alpha());
468                                 }
469                                 colors += 3;
470                         }
471                 } // loop over strip vertices
472 #if 0
473                 BKE_mesh_validate(mesh, TRUE);
474 #endif
475         } // loop over strips
476 }
477
478 // A replacement of BKE_object_add() for better performance.
479 Object *BlenderStrokeRenderer::NewMesh() const
480 {
481         Object *ob;
482         Base *base;
483         char name[MAX_ID_NAME];
484         unsigned int mesh_id = get_stroke_mesh_id();
485
486         BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
487         ob = BKE_object_add_only_object(G.main, OB_MESH, name);
488         BLI_snprintf(name, MAX_ID_NAME, "0%08xME", mesh_id);
489         ob->data = BKE_mesh_add(G.main, name);
490         ob->lay = 1;
491
492         base = BKE_scene_base_add(freestyle_scene, ob);
493 #if 0
494         BKE_scene_base_deselect_all(scene);
495         BKE_scene_base_select(scene, base);
496 #else
497         (void)base;
498 #endif
499         ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
500
501         return ob;
502 }
503
504 Render *BlenderStrokeRenderer::RenderScene(Render *re)
505 {
506         Camera *camera = (Camera *)freestyle_scene->camera->data;
507         if (camera->clipend < _z)
508                 camera->clipend = _z + _z_delta * 100.0f;
509 #if 0
510         if (G.debug & G_DEBUG_FREESTYLE) {
511                 cout << "clipsta " << camera->clipsta << ", clipend " << camera->clipend << endl;
512         }
513 #endif
514
515         Render *freestyle_render = RE_NewRender(freestyle_scene->id.name);
516
517         RE_RenderFreestyleStrokes(freestyle_render, G.main, freestyle_scene);
518         return freestyle_render;
519 }