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