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