Freestyle: Fix for missing quality control on line rendering in Cycles.
[blender.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  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
22  *  \ingroup freestyle
23  */
24
25 #include "BlenderStrokeRenderer.h"
26
27 #include "../application/AppConfig.h"
28 #include "../stroke/Canvas.h"
29
30 extern "C" {
31 #include "MEM_guardedalloc.h"
32
33 #include "RNA_access.h"
34 #include "RNA_types.h"
35
36 #include "DNA_camera_types.h"
37 #include "DNA_listBase.h"
38 #include "DNA_linestyle_types.h"
39 #include "DNA_material_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_scene_types.h"
45
46 #include "BKE_customdata.h"
47 #include "BKE_depsgraph.h"
48 #include "BKE_global.h"
49 #include "BKE_library.h" /* free_libblock */
50 #include "BKE_material.h"
51 #include "BKE_mesh.h"
52 #include "BKE_node.h"
53 #include "BKE_object.h"
54 #include "BKE_scene.h"
55
56 #include "BLI_ghash.h"
57 #include "BLI_listbase.h"
58 #include "BLI_utildefines.h"
59
60 #include "RE_pipeline.h"
61
62 #include "render_types.h"
63 }
64
65 #include <limits.h>
66
67 namespace Freestyle {
68
69 BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
70 {
71         freestyle_bmain = re->freestyle_bmain;
72
73         // for stroke mesh generation
74         _width = re->winx;
75         _height = re->winy;
76
77         old_scene = re->scene;
78
79         char name[MAX_ID_NAME - 2];
80         BLI_snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name + 2);
81         freestyle_scene = BKE_scene_add(freestyle_bmain, name);
82         freestyle_scene->r.cfra = old_scene->r.cfra;
83         freestyle_scene->r.mode = old_scene->r.mode &
84                                   ~(R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER);
85         freestyle_scene->r.xsch = re->rectx; // old_scene->r.xsch
86         freestyle_scene->r.ysch = re->recty; // old_scene->r.ysch
87         freestyle_scene->r.xasp = 1.0f; // old_scene->r.xasp;
88         freestyle_scene->r.yasp = 1.0f; // old_scene->r.yasp;
89         freestyle_scene->r.tilex = old_scene->r.tilex;
90         freestyle_scene->r.tiley = old_scene->r.tiley;
91         freestyle_scene->r.size = 100; // old_scene->r.size
92         //freestyle_scene->r.maximsize = old_scene->r.maximsize; /* DEPRECATED */
93         freestyle_scene->r.ocres = old_scene->r.ocres;
94         freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag;
95         freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER | R_NO_FRAME_UPDATE);
96         freestyle_scene->r.flag = old_scene->r.flag;
97         freestyle_scene->r.threads = old_scene->r.threads;
98         freestyle_scene->r.border.xmin = old_scene->r.border.xmin;
99         freestyle_scene->r.border.ymin = old_scene->r.border.ymin;
100         freestyle_scene->r.border.xmax = old_scene->r.border.xmax;
101         freestyle_scene->r.border.ymax = old_scene->r.border.ymax;
102         strcpy(freestyle_scene->r.pic, old_scene->r.pic);
103         freestyle_scene->r.safety.xmin = old_scene->r.safety.xmin;
104         freestyle_scene->r.safety.ymin = old_scene->r.safety.ymin;
105         freestyle_scene->r.safety.xmax = old_scene->r.safety.xmax;
106         freestyle_scene->r.safety.ymax = old_scene->r.safety.ymax;
107         freestyle_scene->r.osa = old_scene->r.osa;
108         freestyle_scene->r.filtertype = old_scene->r.filtertype;
109         freestyle_scene->r.gauss = old_scene->r.gauss;
110         freestyle_scene->r.dither_intensity = old_scene->r.dither_intensity;
111         BLI_strncpy(freestyle_scene->r.engine, old_scene->r.engine, sizeof(freestyle_scene->r.engine));
112         freestyle_scene->r.im_format.planes = R_IMF_PLANES_RGBA; 
113         freestyle_scene->r.im_format.imtype = R_IMF_IMTYPE_PNG;
114         BKE_scene_disable_color_management(freestyle_scene);
115
116         if (G.debug & G_DEBUG_FREESTYLE) {
117                 printf("%s: %d thread(s)\n", __func__, BKE_render_num_threads(&freestyle_scene->r));
118         }
119
120         // Render layer
121         SceneRenderLayer *srl = (SceneRenderLayer *)freestyle_scene->r.layers.first;
122         srl->layflag = SCE_LAY_SOLID | SCE_LAY_ZTRA;
123
124         BKE_scene_set_background(freestyle_bmain, freestyle_scene);
125
126         // Camera
127         Object *object_camera = BKE_object_add(freestyle_bmain, freestyle_scene, OB_CAMERA);
128
129         Camera *camera = (Camera *)object_camera->data;
130         camera->type = CAM_ORTHO;
131         camera->ortho_scale = max(re->rectx, re->recty);
132         camera->clipsta = 0.1f;
133         camera->clipend = 100.0f;
134
135         _z_delta = 0.00001f;
136         _z = camera->clipsta + _z_delta;
137
138         object_camera->loc[0] = re->disprect.xmin + 0.5f * re->rectx;
139         object_camera->loc[1] = re->disprect.ymin + 0.5f * re->recty;
140         object_camera->loc[2] = 1.0f;
141
142         freestyle_scene->camera = object_camera;
143
144         // Reset serial mesh ID (used for BlenderStrokeRenderer::NewMesh())
145         _mesh_id = 0xffffffff;
146
147         // Check if the rendering engine uses new shading nodes
148         _use_shading_nodes = BKE_scene_use_new_shading_nodes(freestyle_scene);
149
150         // Create a bNodeTree-to-Material hash table
151         if (_use_shading_nodes)
152                 _nodetree_hash = BLI_ghash_ptr_new("BlenderStrokeRenderer::_nodetree_hash");
153         else
154                 _nodetree_hash = NULL;
155 }
156
157 BlenderStrokeRenderer::~BlenderStrokeRenderer()
158 {
159         // The freestyle_scene object is not released here.  Instead,
160         // the scene is released in free_all_freestyle_renders() in
161         // source/blender/render/intern/source/pipeline.c, after the
162         // compositor has finished.
163
164         // release objects and data blocks
165         for (Base *b = (Base *)freestyle_scene->base.first; b; b = b->next) {
166                 Object *ob = b->object;
167                 void *data = ob->data;
168                 char *name = ob->id.name;
169 #if 0
170                 if (G.debug & G_DEBUG_FREESTYLE) {
171                         cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl;
172                 }
173 #endif
174                 switch (ob->type) {
175                 case OB_MESH:
176                         BKE_libblock_free(freestyle_bmain, ob);
177                         BKE_libblock_free(freestyle_bmain, data);
178                         break;
179                 case OB_CAMERA:
180                         BKE_libblock_free(freestyle_bmain, ob);
181                         BKE_libblock_free(freestyle_bmain, data);
182                         freestyle_scene->camera = NULL;
183                         break;
184                 default:
185                         cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name + 2) << endl;
186                 }
187         }
188         BLI_freelistN(&freestyle_scene->base);
189
190         // release materials
191         Link *lnk = (Link *)freestyle_bmain->mat.first;
192
193         while (lnk)
194         {
195                 Material *ma = (Material*)lnk;
196                 // We want to retain the linestyle mtexs, so let's detach them first
197                 for (int a = 0; a < MAX_MTEX; a++) {
198                         if (ma->mtex[a]) {
199                                 ma->mtex[a] = NULL;
200                         }
201                         else {
202                                 break; // Textures are ordered, no empty slots between two textures
203                         }
204                 }
205                 lnk = lnk->next;
206                 BKE_libblock_free(freestyle_bmain, ma);
207         }
208
209         if (_use_shading_nodes)
210                 BLI_ghash_free(_nodetree_hash, NULL, NULL);
211 }
212
213 float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
214 {
215         float z = _z;
216         BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
217         if (!(_z < _z_delta * 100000.0f))
218                 self->_z_delta *= 10.0f;
219         self->_z += _z_delta;
220         return -z;
221 }
222
223 unsigned int BlenderStrokeRenderer::get_stroke_mesh_id(void) const
224 {
225         unsigned mesh_id = _mesh_id;
226         BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this);
227         self->_mesh_id--;
228         return mesh_id;
229 }
230
231 Material* BlenderStrokeRenderer::GetStrokeShader(Main *bmain, bNodeTree *iNodeTree, bool do_id_user)
232 {
233         Material *ma = BKE_material_add(bmain, "stroke_shader");
234         bNodeTree *ntree;
235         bNode *output_linestyle = NULL;
236         bNodeSocket *fromsock, *tosock;
237         PointerRNA fromptr, toptr;
238         NodeShaderAttribute *storage;
239
240         if (iNodeTree) {
241                 // make a copy of linestyle->nodetree
242                 ntree = ntreeCopyTree_ex(iNodeTree, bmain, do_id_user);
243
244                 // find the active Output Line Style node
245                 for (bNode *node = (bNode *)ntree->nodes.first; node; node = node->next) {
246                         if (node->type == SH_NODE_OUTPUT_LINESTYLE && (node->flag & NODE_DO_OUTPUT)) {
247                                 output_linestyle = node;
248                                 break;
249                         }
250                 }
251         }
252         else {
253                 ntree = ntreeAddTree(NULL, "stroke_shader", "ShaderNodeTree");
254         }
255         ma->nodetree = ntree;
256         ma->use_nodes = 1;
257
258         bNode *input_attr_color = nodeAddStaticNode(NULL, ntree, SH_NODE_ATTRIBUTE);
259         input_attr_color->locx = 0.0f;
260         input_attr_color->locy = -200.0f;
261         storage = (NodeShaderAttribute *)input_attr_color->storage;
262         BLI_strncpy(storage->name, "Color", sizeof(storage->name));
263
264         bNode *mix_rgb_color = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_RGB);
265         mix_rgb_color->custom1 = MA_RAMP_BLEND; // Mix
266         mix_rgb_color->locx = 200.0f;
267         mix_rgb_color->locy = -200.0f;
268         tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 0); // Fac
269         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
270         RNA_float_set(&toptr, "default_value", 0.0f);
271
272         bNode *input_attr_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_ATTRIBUTE);
273         input_attr_alpha->locx = 400.0f;
274         input_attr_alpha->locy = 300.0f;
275         storage = (NodeShaderAttribute *)input_attr_alpha->storage;
276         BLI_strncpy(storage->name, "Alpha", sizeof(storage->name));
277
278         bNode *mix_rgb_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_RGB);
279         mix_rgb_alpha->custom1 = MA_RAMP_BLEND; // Mix
280         mix_rgb_alpha->locx = 600.0f;
281         mix_rgb_alpha->locy = 300.0f;
282         tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 0); // Fac
283         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
284         RNA_float_set(&toptr, "default_value", 0.0f);
285
286         bNode *shader_emission = nodeAddStaticNode(NULL, ntree, SH_NODE_EMISSION);
287         shader_emission->locx = 400.0f;
288         shader_emission->locy = -200.0f;
289
290         bNode *input_light_path = nodeAddStaticNode(NULL, ntree, SH_NODE_LIGHT_PATH);
291         input_light_path->locx = 400.0f;
292         input_light_path->locy = 100.0f;
293
294         bNode *mix_shader_color = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_SHADER);
295         mix_shader_color->locx = 600.0f;
296         mix_shader_color->locy = -100.0f;
297
298         bNode *shader_transparent = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_TRANSPARENT);
299         shader_transparent->locx = 600.0f;
300         shader_transparent->locy = 100.0f;
301
302         bNode *mix_shader_alpha = nodeAddStaticNode(NULL, ntree, SH_NODE_MIX_SHADER);
303         mix_shader_alpha->locx = 800.0f;
304         mix_shader_alpha->locy = 100.0f;
305
306         bNode *output_material = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
307         output_material->locx = 1000.0f;
308         output_material->locy = 100.0f;
309
310         fromsock = (bNodeSocket *)BLI_findlink(&input_attr_color->outputs, 0); // Color
311         tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 1); // Color1
312         nodeAddLink(ntree, input_attr_color, fromsock, mix_rgb_color, tosock);
313
314         fromsock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->outputs, 0); // Color
315         tosock = (bNodeSocket *)BLI_findlink(&shader_emission->inputs, 0); // Color
316         nodeAddLink(ntree, mix_rgb_color, fromsock, shader_emission, tosock);
317
318         fromsock = (bNodeSocket *)BLI_findlink(&shader_emission->outputs, 0); // Emission
319         tosock = (bNodeSocket *)BLI_findlink(&mix_shader_color->inputs, 2); // Shader (second)
320         nodeAddLink(ntree, shader_emission, fromsock, mix_shader_color, tosock);
321
322         fromsock = (bNodeSocket *)BLI_findlink(&input_light_path->outputs, 0); // In Camera Ray
323         tosock = (bNodeSocket *)BLI_findlink(&mix_shader_color->inputs, 0); // Fac
324         nodeAddLink(ntree, input_light_path, fromsock, mix_shader_color, tosock);
325
326         fromsock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->outputs, 0); // Color
327         tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 0); // Fac
328         nodeAddLink(ntree, mix_rgb_alpha, fromsock, mix_shader_alpha, tosock);
329
330         fromsock = (bNodeSocket *)BLI_findlink(&input_attr_alpha->outputs, 0); // Color
331         tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 1); // Color1
332         nodeAddLink(ntree, input_attr_alpha, fromsock, mix_rgb_alpha, tosock);
333
334         fromsock = (bNodeSocket *)BLI_findlink(&shader_transparent->outputs, 0); // BSDF
335         tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 1); // Shader (first)
336         nodeAddLink(ntree, shader_transparent, fromsock, mix_shader_alpha, tosock);
337
338         fromsock = (bNodeSocket *)BLI_findlink(&mix_shader_color->outputs, 0); // Shader
339         tosock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->inputs, 2); // Shader (second)
340         nodeAddLink(ntree, mix_shader_color, fromsock, mix_shader_alpha, tosock);
341
342         fromsock = (bNodeSocket *)BLI_findlink(&mix_shader_alpha->outputs, 0); // Shader
343         tosock = (bNodeSocket *)BLI_findlink(&output_material->inputs, 0); // Surface
344         nodeAddLink(ntree, mix_shader_alpha, fromsock, output_material, tosock);
345
346         if (output_linestyle) {
347                 bNodeSocket *outsock;
348                 bNodeLink *link;
349
350                 mix_rgb_color->custom1 = output_linestyle->custom1; // blend_type
351                 mix_rgb_color->custom2 = output_linestyle->custom2; // use_clamp
352
353                 outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 0); // Color
354                 tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 2); // Color2
355                 link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
356                 if (link) {
357                         nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_color, tosock);
358                 }
359                 else {
360                         float color[4];
361                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
362                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
363                         RNA_float_get_array(&fromptr, "default_value", color);
364                         RNA_float_set_array(&toptr, "default_value", color);
365                 }
366
367                 outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 1); // Color Fac
368                 tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_color->inputs, 0); // Fac
369                 link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
370                 if (link) {
371                         nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_color, tosock);
372                 }
373                 else {
374                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
375                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
376                         RNA_float_set(&toptr, "default_value", RNA_float_get(&fromptr, "default_value"));
377                 }
378
379                 outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 2); // Alpha
380                 tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 2); // Color2
381                 link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
382                 if (link) {
383                         nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_alpha, tosock);
384                 }
385                 else {
386                         float color[4];
387                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
388                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
389                         color[0] = color[1] = color[2] = RNA_float_get(&fromptr, "default_value");
390                         color[3] = 1.0f;
391                         RNA_float_set_array(&toptr, "default_value", color);
392                 }
393
394                 outsock = (bNodeSocket *)BLI_findlink(&output_linestyle->inputs, 3); // Alpha Fac
395                 tosock = (bNodeSocket *)BLI_findlink(&mix_rgb_alpha->inputs, 0); // Fac
396                 link = (bNodeLink *)BLI_findptr(&ntree->links, outsock, offsetof(bNodeLink, tosock));
397                 if (link) {
398                         nodeAddLink(ntree, link->fromnode, link->fromsock, mix_rgb_alpha, tosock);
399                 }
400                 else {
401                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, outsock, &fromptr);
402                         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, tosock, &toptr);
403                         RNA_float_set(&toptr, "default_value", RNA_float_get(&fromptr, "default_value"));
404                 }
405
406                 for (bNode *node = (bNode *)ntree->nodes.first; node; node = node->next) {
407                         if (node->type == SH_NODE_UVALONGSTROKE) {
408                                 // UV output of the UV Along Stroke node
409                                 bNodeSocket *sock = (bNodeSocket *)BLI_findlink(&node->outputs, 0);
410
411                                 // add new UV Map node
412                                 bNode *input_uvmap = nodeAddStaticNode(NULL, ntree, SH_NODE_UVMAP);
413                                 input_uvmap->locx = node->locx - 200.0f;
414                                 input_uvmap->locy = node->locy;
415                                 NodeShaderUVMap *storage = (NodeShaderUVMap *)input_uvmap->storage;
416                                 if (node->custom1 & 1) { // use_tips
417                                         BLI_strncpy(storage->uv_map, "along_stroke_tips", sizeof(storage->uv_map));
418                                 }
419                                 else {
420                                         BLI_strncpy(storage->uv_map, "along_stroke", sizeof(storage->uv_map));
421                                 }
422                                 fromsock = (bNodeSocket *)BLI_findlink(&input_uvmap->outputs, 0); // UV
423
424                                 // replace links from the UV Along Stroke node by links from the UV Map node
425                                 for (bNodeLink *link = (bNodeLink *)ntree->links.first; link; link = link->next) {
426                                         if (link->fromnode == node && link->fromsock == sock) {
427                                                 nodeAddLink(ntree, input_uvmap, fromsock, link->tonode, link->tosock);
428                                         }
429                                 }
430                                 nodeRemSocketLinks(ntree, sock);
431                         }
432                 }
433         }
434
435         nodeSetActive(ntree, output_material);
436         ntreeUpdateTree(bmain, ntree);
437
438         return ma;
439 }
440
441 void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
442 {
443         if (_use_shading_nodes) {
444                 bNodeTree *nt = iStrokeRep->getNodeTree();
445                 Material *ma = (Material *)BLI_ghash_lookup(_nodetree_hash, nt);
446                 if (!ma) {
447                         ma = BlenderStrokeRenderer::GetStrokeShader(freestyle_bmain, nt, false);
448                         BLI_ghash_insert(_nodetree_hash, nt, ma);
449                 }
450
451                 if (strcmp(freestyle_scene->r.engine, "CYCLES") == 0) {
452                         PointerRNA scene_ptr, freestyle_scene_ptr;
453                         RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr);
454                         RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr);
455
456                         PointerRNA cycles_ptr = RNA_pointer_get(&scene_ptr, "cycles");
457                         PointerRNA freestyle_cycles_ptr = RNA_pointer_get(&freestyle_scene_ptr, "cycles");
458
459                         int flag;
460                         RNA_STRUCT_BEGIN(&freestyle_cycles_ptr, prop)
461                         {
462                                 flag = RNA_property_flag(prop);
463                                 if (flag & PROP_HIDDEN)
464                                         continue;
465                                 RNA_property_copy(&freestyle_cycles_ptr, &cycles_ptr, prop, -1);
466                         }
467                         RNA_STRUCT_END;
468
469                         RNA_boolean_set(&freestyle_cycles_ptr, "film_transparent", 1);
470                 }
471
472                 iStrokeRep->setMaterial(ma);
473         }
474         else {
475                 bool has_mat = false;
476                 int a = 0;
477
478                 // Look for a good existing material
479                 for (Link *lnk = (Link *)freestyle_bmain->mat.first; lnk; lnk = lnk->next) {
480                         Material *ma = (Material*)lnk;
481                         bool texs_are_good = true;
482                         // as soon as textures differ it's not the right one
483                         for (int a = 0; a < MAX_MTEX; a++) {
484                                 if (ma->mtex[a] != iStrokeRep->getMTex(a)) {
485                                         texs_are_good = false;
486                                         break;
487                                 }
488                         }
489
490                         if (texs_are_good) {
491                                 iStrokeRep->setMaterial(ma);
492                                 has_mat = true;
493                                 break; // if textures are good, no need to search anymore
494                         }
495                 }
496
497                 // If still no material, create one
498                 if (!has_mat) {
499                         Material *ma = BKE_material_add(freestyle_bmain, "stroke_material");
500                         ma->mode |= MA_VERTEXCOLP;
501                         ma->mode |= MA_TRANSP;
502                         ma->mode |= MA_SHLESS;
503                         ma->vcol_alpha = 1;
504
505                         // Textures
506                         while (iStrokeRep->getMTex(a)) {
507                                 ma->mtex[a] = (MTex *)iStrokeRep->getMTex(a);
508
509                                 // We'll generate both with tips and without tips
510                                 // coordinates, on two different UV layers.
511                                 if (ma->mtex[a]->texflag & MTEX_TIPS)  {
512                                         BLI_strncpy(ma->mtex[a]->uvname, "along_stroke_tips", sizeof(ma->mtex[a]->uvname));
513                                 }
514                                 else {
515                                         BLI_strncpy(ma->mtex[a]->uvname, "along_stroke", sizeof(ma->mtex[a]->uvname));
516                                 }
517                                 a++;
518                         }
519
520                         iStrokeRep->setMaterial(ma);
521                 }
522         }
523
524         RenderStrokeRepBasic(iStrokeRep);
525 }
526
527 // Check if the triangle is visible (i.e., within the render image boundary)
528 bool BlenderStrokeRenderer::test_triangle_visibility(StrokeVertexRep *svRep[3]) const
529 {
530         int xl, xu, yl, yu;
531         Vec2r p;
532
533         xl = xu = yl = yu = 0;
534         for (int i = 0; i < 3; i++) {
535                 p = svRep[i]->point2d();
536                 if (p[0] < 0.0)
537                         xl++;
538                 else if (p[0] > _width)
539                         xu++;
540                 if (p[1] < 0.0)
541                         yl++;
542                 else if (p[1] > _height)
543                         yu++;
544         }
545         return !(xl == 3 || xu == 3 || yl == 3 || yu == 3);
546 }
547
548 // Check the visibility of faces and strip segments.
549 void BlenderStrokeRenderer::test_strip_visibility(Strip::vertex_container& strip_vertices,
550         int *visible_faces, int *visible_segments) const
551 {
552         const int strip_vertex_count = strip_vertices.size();
553         Strip::vertex_container::iterator v[3];
554         StrokeVertexRep *svRep[3];
555         bool visible;
556
557         // iterate over all vertices and count visible faces and strip segments
558         // (note: a strip segment is a series of visible faces, while two strip
559         // segments are separated by one or more invisible faces)
560         v[0] = strip_vertices.begin();
561         v[1] = v[0] + 1;
562         v[2] = v[0] + 2;
563         *visible_faces = *visible_segments = 0;
564         visible = false;
565         for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
566                 svRep[0] = *(v[0]);
567                 svRep[1] = *(v[1]);
568                 svRep[2] = *(v[2]);
569                 if (test_triangle_visibility(svRep)) {
570                         (*visible_faces)++;
571                         if (!visible)
572                                 (*visible_segments)++;
573                         visible = true;
574                 }
575                 else {
576                         visible = false;
577                 }
578         }
579 }
580
581 // Build a mesh object representing a stroke
582 void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
583 {
584         vector<Strip*>& strips = iStrokeRep->getStrips();
585         const bool hasTex = iStrokeRep->hasTex();
586         Strip::vertex_container::iterator v[3];
587         StrokeVertexRep *svRep[3];
588         unsigned int vertex_index, edge_index, loop_index;
589         Vec2r p;
590
591         int totvert = 0, totedge = 0, totpoly = 0, totloop = 0;
592         int visible_faces, visible_segments;
593
594         bool visible;
595         for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
596                 Strip::vertex_container& strip_vertices = (*s)->vertices();
597
598                 // count visible faces and strip segments
599                 test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
600                 if (visible_faces == 0)
601                         continue;
602
603                 totvert += visible_faces + visible_segments * 2;
604                 totedge += visible_faces * 2 + visible_segments;
605                 totpoly += visible_faces;
606                 totloop += visible_faces * 3;
607         }
608
609 #if 0
610         Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, OB_MESH);
611 #else
612         Object *object_mesh = NewMesh();
613 #endif
614         Mesh *mesh = (Mesh *)object_mesh->data;
615         mesh->mat = (Material **)MEM_mallocN(1 * sizeof(Material *), "MaterialList");
616         mesh->mat[0] = iStrokeRep->getMaterial();
617         mesh->totcol = 1;
618         test_object_materials(freestyle_bmain, (ID *)mesh);
619
620         // vertices allocation
621         mesh->totvert = totvert; // visible_faces + visible_segments * 2;
622         CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
623
624         // edges allocation
625         mesh->totedge = totedge; // visible_faces * 2 + visible_segments;
626         CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
627
628         // faces allocation
629         mesh->totpoly = totpoly; // visible_faces;
630         CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
631
632         // loops allocation
633         mesh->totloop = totloop; // visible_faces * 3;
634         CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
635
636         // uv maps
637         MLoopUV *loopsuv[2] = { NULL };
638         if (hasTex) {
639                 loopsuv[0] = (MLoopUV *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke");
640                 loopsuv[1] = (MLoopUV *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke_tips");
641
642                 CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke");
643                 CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke_tips");
644         }
645
646         // colors and transparency (the latter represented by grayscale colors)
647         MLoopCol *colors = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Color");
648         MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Alpha");
649
650         BKE_mesh_update_customdata_pointers(mesh, true);
651
652         ////////////////////
653         //  Data copy
654         ////////////////////
655
656         MVert *vertices = mesh->mvert;
657         MEdge *edges = mesh->medge;
658         MPoly *polys = mesh->mpoly;
659         MLoop *loops = mesh->mloop;
660
661         vertex_index = edge_index = loop_index = 0;
662
663         for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
664                 Strip::vertex_container& strip_vertices = (*s)->vertices();
665                 int strip_vertex_count = strip_vertices.size();
666
667                 // count visible faces and strip segments
668                 test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
669                 if (visible_faces == 0)
670                         continue;
671
672                 v[0] = strip_vertices.begin();
673                 v[1] = v[0] + 1;
674                 v[2] = v[0] + 2;
675
676                 visible = false;
677
678                 // Note: Mesh generation in the following loop assumes stroke strips
679                 // to be triangle strips.
680                 for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
681                         svRep[0] = *(v[0]);
682                         svRep[1] = *(v[1]);
683                         svRep[2] = *(v[2]);
684                         if (!test_triangle_visibility(svRep)) {
685                                 visible = false;
686                         }
687                         else {
688                                 if (!visible) {
689                                         // first vertex
690                                         vertices->co[0] = svRep[0]->point2d()[0];
691                                         vertices->co[1] = svRep[0]->point2d()[1];
692                                         vertices->co[2] = get_stroke_vertex_z();
693                                         vertices->no[0] = 0;
694                                         vertices->no[1] = 0;
695                                         vertices->no[2] = SHRT_MAX;
696                                         ++vertices;
697                                         ++vertex_index;
698
699                                         // second vertex
700                                         vertices->co[0] = svRep[1]->point2d()[0];
701                                         vertices->co[1] = svRep[1]->point2d()[1];
702                                         vertices->co[2] = get_stroke_vertex_z();
703                                         vertices->no[0] = 0;
704                                         vertices->no[1] = 0;
705                                         vertices->no[2] = SHRT_MAX;
706                                         ++vertices;
707                                         ++vertex_index;
708
709                                         // first edge
710                                         edges->v1 = vertex_index - 2;
711                                         edges->v2 = vertex_index - 1;
712                                         ++edges;
713                                         ++edge_index;
714                                 }
715                                 visible = true;
716
717                                 // vertex
718                                 vertices->co[0] = svRep[2]->point2d()[0];
719                                 vertices->co[1] = svRep[2]->point2d()[1];
720                                 vertices->co[2] = get_stroke_vertex_z();
721                                 vertices->no[0] = 0;
722                                 vertices->no[1] = 0;
723                                 vertices->no[2] = SHRT_MAX;
724                                 ++vertices;
725                                 ++vertex_index;
726
727                                 // edges
728                                 edges->v1 = vertex_index - 1;
729                                 edges->v2 = vertex_index - 3;
730                                 ++edges;
731                                 ++edge_index;
732
733                                 edges->v1 = vertex_index - 1;
734                                 edges->v2 = vertex_index - 2;
735                                 ++edges;
736                                 ++edge_index;
737
738                                 // poly
739                                 polys->loopstart = loop_index;
740                                 polys->totloop = 3;
741                                 ++polys;
742
743                                 // Even and odd loops connect triangles vertices differently
744                                 bool is_odd = n % 2;
745                                 // loops
746                                 if (is_odd) {
747                                         loops[0].v = vertex_index - 1;
748                                         loops[0].e = edge_index - 2;
749
750                                         loops[1].v = vertex_index - 3;
751                                         loops[1].e = edge_index - 3;
752
753                                         loops[2].v = vertex_index - 2;
754                                         loops[2].e = edge_index - 1;
755                                 }
756                                 else {
757                                         loops[0].v = vertex_index - 1;
758                                         loops[0].e = edge_index - 1;
759
760                                         loops[1].v = vertex_index - 2;
761                                         loops[1].e = edge_index - 3;
762
763                                         loops[2].v = vertex_index - 3;
764                                         loops[2].e = edge_index - 2;
765                                 }
766                                 loops += 3;
767                                 loop_index += 3;
768
769                                 // UV
770                                 if (hasTex) {
771                                         // First UV layer (loopsuv[0]) has no tips (texCoord(0)).
772                                         // Second UV layer (loopsuv[1]) has tips:  (texCoord(1)).
773                                         for (int L = 0; L < 2; L++) {
774                                                 if (is_odd) {
775                                                         loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
776                                                         loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
777
778                                                         loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
779                                                         loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
780
781                                                         loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
782                                                         loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
783                                                 }
784                                                 else {
785                                                         loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
786                                                         loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
787
788                                                         loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
789                                                         loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
790
791                                                         loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
792                                                         loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
793                                                 }
794                                                 loopsuv[L] += 3;
795                                         }
796                                 }
797
798                                 // colors and alpha transparency
799                                 if (is_odd) {
800                                         colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
801                                         colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
802                                         colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
803                                         colors[0].a = (short)(255.0f * svRep[2]->alpha());
804
805                                         colors[1].r = (short)(255.0f * svRep[0]->color()[0]);
806                                         colors[1].g = (short)(255.0f * svRep[0]->color()[1]);
807                                         colors[1].b = (short)(255.0f * svRep[0]->color()[2]);
808                                         colors[1].a = (short)(255.0f * svRep[0]->alpha());
809
810                                         colors[2].r = (short)(255.0f * svRep[1]->color()[0]);
811                                         colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
812                                         colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
813                                         colors[2].a = (short)(255.0f * svRep[1]->alpha());
814                                 }
815                                 else {
816                                         colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
817                                         colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
818                                         colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
819                                         colors[0].a = (short)(255.0f * svRep[2]->alpha());
820
821                                         colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
822                                         colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
823                                         colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
824                                         colors[1].a = (short)(255.0f * svRep[1]->alpha());
825
826                                         colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
827                                         colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
828                                         colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
829                                         colors[2].a = (short)(255.0f * svRep[0]->alpha());
830                                 }
831                                 transp[0].r = transp[0].g = transp[0].b = colors[0].a;
832                                 transp[1].r = transp[1].g = transp[1].b = colors[1].a;
833                                 transp[2].r = transp[2].g = transp[2].b = colors[2].a;
834                                 colors += 3;
835                                 transp += 3;
836                         }
837                 } // loop over strip vertices
838         } // loop over strips
839 #if 0
840         BLI_assert(totvert == vertex_index);
841         BLI_assert(totedge == edge_index);
842         BLI_assert(totloop == loop_index);
843         BKE_mesh_validate(mesh, true);
844 #endif
845 }
846
847 // A replacement of BKE_object_add() for better performance.
848 Object *BlenderStrokeRenderer::NewMesh() const
849 {
850         Object *ob;
851         Base *base;
852         char name[MAX_ID_NAME];
853         unsigned int mesh_id = get_stroke_mesh_id();
854
855         BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
856         ob = BKE_object_add_only_object(freestyle_bmain, OB_MESH, name);
857         BLI_snprintf(name, MAX_ID_NAME, "0%08xME", mesh_id);
858         ob->data = BKE_mesh_add(freestyle_bmain, name);
859         ob->lay = 1;
860
861         base = BKE_scene_base_add(freestyle_scene, ob);
862 #if 0
863         BKE_scene_base_deselect_all(scene);
864         BKE_scene_base_select(scene, base);
865 #else
866         (void)base;
867 #endif
868
869         DAG_id_tag_update_ex(freestyle_bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
870
871         return ob;
872 }
873
874 Render *BlenderStrokeRenderer::RenderScene(Render *re, bool render)
875 {
876         Camera *camera = (Camera *)freestyle_scene->camera->data;
877         if (camera->clipend < _z)
878                 camera->clipend = _z + _z_delta * 100.0f;
879 #if 0
880         if (G.debug & G_DEBUG_FREESTYLE) {
881                 cout << "clipsta " << camera->clipsta << ", clipend " << camera->clipend << endl;
882         }
883 #endif
884
885         Render *freestyle_render = RE_NewRender(freestyle_scene->id.name);
886
887         RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene, render);
888
889         return freestyle_render;
890 }
891
892 } /* namespace Freestyle */