Blender V4.3
FRS_freestyle.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <iostream>
10#include <map>
11#include <set>
12
17
19
20using namespace std;
21using namespace Freestyle;
22
23#include "MEM_guardedalloc.h"
24
25#include "DNA_camera_types.h"
27#include "DNA_freestyle_types.h"
28#include "DNA_material_types.h"
29#include "DNA_text_types.h"
30
31#include "BKE_callbacks.hh"
32#include "BKE_context.hh"
33#include "BKE_freestyle.h"
34#include "BKE_global.hh"
35#include "BKE_lib_id.hh"
36#include "BKE_linestyle.h"
37#include "BKE_scene.hh"
38#include "BKE_text.h"
39
40#include "BLT_translation.hh"
41
42#include "BLI_blenlib.h"
44#include "BLI_math_matrix.h"
45#include "BLI_math_rotation.h"
46
47#include "BPY_extern.hh"
48
50
51#include "IMB_imbuf.hh"
52
53#include "pipeline.hh"
54
55#include "FRS_freestyle.h"
56
57extern "C" {
58
60
61// Freestyle configuration
62static bool freestyle_is_initialized = false;
63static Config::Path *pathconfig = nullptr;
64static Controller *controller = nullptr;
65static AppView *view = nullptr;
66
67// line set buffer for copy & paste
69static bool lineset_copied = false;
70
71static void load_post_callback(Main * /*main*/,
72 PointerRNA ** /*pointers*/,
73 const int /*num_pointers*/,
74 void * /*arg*/)
75{
76 lineset_copied = false;
77}
78
80 /*next*/ nullptr,
81 /*prev*/ nullptr,
82 /*func*/ load_post_callback,
83 /*arg*/ nullptr,
84 /*alloc*/ 0};
85
86//=======================================================
87// Initialization
88//=======================================================
89
91{
93 return;
94 }
95
97 controller = new Controller();
98 view = new AppView;
99 controller->setView(view);
100 controller->Clear();
101 g_freestyle.scene = nullptr;
102 lineset_copied = false;
103
105
107}
108
110{
111 if (G.debug & G_DEBUG_FREESTYLE) {
112 cout << "FRS_set_context: context 0x" << C << " scene 0x" << CTX_data_scene(C) << endl;
113 }
115}
116
118{
119 delete pathconfig;
120 delete controller;
121 delete view;
122}
123
124//=======================================================
125// Rendering
126//=======================================================
127
128static void init_view(Render *re)
129{
130 int width = re->winx;
131 int height = re->winy;
132 int xmin = re->disprect.xmin;
133 int ymin = re->disprect.ymin;
134 int xmax = re->disprect.xmax;
135 int ymax = re->disprect.ymax;
136
137 float thickness = 1.0f;
138 switch (re->scene->r.line_thickness_mode) {
140 thickness = re->scene->r.unit_line_thickness * (re->r.size / 100.0f);
141 break;
143 thickness = height / 480.0f;
144 break;
145 }
146
148 g_freestyle.viewport[2] = width;
149 g_freestyle.viewport[3] = height;
150
151 view->setWidth(width);
152 view->setHeight(height);
153 view->setBorder(xmin, ymin, xmax, ymax);
154 view->setThickness(thickness);
155
156 if (G.debug & G_DEBUG_FREESTYLE) {
157 cout << "\n=== Dimensions of the 2D image coordinate system ===" << endl;
158 cout << "Width : " << width << endl;
159 cout << "Height : " << height << endl;
160 if (re->r.mode & R_BORDER) {
161 cout << "Border : (" << xmin << ", " << ymin << ") - (" << xmax << ", " << ymax << ")"
162 << endl;
163 }
164 cout << "Unit line thickness : " << thickness << " pixel(s)" << endl;
165 }
166}
167
168static char *escape_quotes(char *name)
169{
170 char *s = (char *)MEM_mallocN(strlen(name) * 2 + 1, "escape_quotes");
171 char *p = s;
172 while (*name) {
173 if (*name == '\'') {
174 *(p++) = '\\';
175 }
176 *(p++) = *(name++);
177 }
178 *p = '\0';
179 return s;
180}
181
182static char *create_lineset_handler(char *layer_name, char *lineset_name)
183{
184 const char *fmt = "__import__('parameter_editor').process('%s', '%s')\n";
185 char *s1 = escape_quotes(layer_name);
186 char *s2 = escape_quotes(lineset_name);
187 char *text = BLI_sprintfN(fmt, s1, s2);
188 MEM_freeN(s1);
189 MEM_freeN(s2);
190 return text;
191}
192
196
197// examines the conditions and returns true if the target edge type needs to be computed
199 int num_edge_types,
200 bool logical_and,
201 int target,
202 bool distinct)
203{
204 int target_condition = 0;
205 int num_non_target_positive_conditions = 0;
206 int num_non_target_negative_conditions = 0;
207
208 for (int i = 0; i < num_edge_types; i++) {
209 if (conditions[i].edge_type == target) {
210 target_condition = conditions[i].value;
211 }
212 else if (conditions[i].value > 0) {
213 ++num_non_target_positive_conditions;
214 }
215 else if (conditions[i].value < 0) {
216 ++num_non_target_negative_conditions;
217 }
218 }
219 if (distinct) {
220 // In this case, the 'target' edge type is assumed to appear on distinct edge
221 // of its own and never together with other edge types.
222 if (logical_and) {
223 if (num_non_target_positive_conditions > 0) {
224 return false;
225 }
226 if (target_condition > 0) {
227 return true;
228 }
229 if (target_condition < 0) {
230 return false;
231 }
232 if (num_non_target_negative_conditions > 0) {
233 return true;
234 }
235 }
236 else {
237 if (target_condition > 0) {
238 return true;
239 }
240 if (num_non_target_negative_conditions > 0) {
241 return true;
242 }
243 if (target_condition < 0) {
244 return false;
245 }
246 if (num_non_target_positive_conditions > 0) {
247 return false;
248 }
249 }
250 }
251 else {
252 // In this case, the 'target' edge type may appear together with other edge types.
253 if (target_condition > 0) {
254 return true;
255 }
256 if (target_condition < 0) {
257 return true;
258 }
259 if (logical_and) {
260 if (num_non_target_positive_conditions > 0) {
261 return false;
262 }
263 if (num_non_target_negative_conditions > 0) {
264 return true;
265 }
266 }
267 else {
268 if (num_non_target_negative_conditions > 0) {
269 return true;
270 }
271 if (num_non_target_positive_conditions > 0) {
272 return false;
273 }
274 }
275 }
276 return true;
277}
278
279static void prepare(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
280{
281 // load mesh
282 re->i.infostr = RPT_("Freestyle: Mesh loading");
283 re->stats_draw(&re->i);
284 re->i.infostr = nullptr;
285 if (controller->LoadMesh(re, view_layer, depsgraph)) {
286 /* Returns if scene cannot be loaded or if empty. */
287 return;
288 }
289 if (re->test_break()) {
290 return;
291 }
292
293 // add style modules
294 FreestyleConfig *config = &view_layer->freestyle_config;
295
296 if (G.debug & G_DEBUG_FREESTYLE) {
297 cout << "\n=== Rendering options ===" << endl;
298 }
299 int layer_count = 0;
300
301 switch (config->mode) {
303 if (G.debug & G_DEBUG_FREESTYLE) {
304 cout << "Modules :" << endl;
305 }
306 LISTBASE_FOREACH (FreestyleModuleConfig *, module_conf, &config->modules) {
307 if (module_conf->script && module_conf->is_displayed) {
308 const char *id_name = module_conf->script->id.name + 2;
309 if (G.debug & G_DEBUG_FREESTYLE) {
310 cout << " " << layer_count + 1 << ": " << id_name;
311 if (module_conf->script->filepath) {
312 cout << " (" << module_conf->script->filepath << ")";
313 }
314 cout << endl;
315 }
316 controller->InsertStyleModule(layer_count, id_name, module_conf->script);
317 controller->toggleLayer(layer_count, true);
318 layer_count++;
319 }
320 }
321 if (G.debug & G_DEBUG_FREESTYLE) {
322 cout << endl;
323 }
325 (config->flags & FREESTYLE_RIDGES_AND_VALLEYS_FLAG) ? true : false);
327 (config->flags & FREESTYLE_SUGGESTIVE_CONTOURS_FLAG) ? true : false);
329 (config->flags & FREESTYLE_MATERIAL_BOUNDARIES_FLAG) ? true : false);
330 break;
332 int use_ridges_and_valleys = 0;
333 int use_suggestive_contours = 0;
334 int use_material_boundaries = 0;
335 edge_type_condition conditions[] = {
345 };
346 int num_edge_types = ARRAY_SIZE(conditions);
347 if (G.debug & G_DEBUG_FREESTYLE) {
348 cout << "Linesets:" << endl;
349 }
350 LISTBASE_FOREACH (FreestyleLineSet *, lineset, &config->linesets) {
351 if (lineset->flags & FREESTYLE_LINESET_ENABLED) {
352 if (G.debug & G_DEBUG_FREESTYLE) {
353 cout << " " << layer_count + 1 << ": " << lineset->name << " - "
354 << (lineset->linestyle ? (lineset->linestyle->id.name + 2) : "<null>") << endl;
355 }
356 char *buffer = create_lineset_handler(view_layer->name, lineset->name);
357 controller->InsertStyleModule(layer_count, lineset->name, buffer);
358 controller->toggleLayer(layer_count, true);
359 MEM_freeN(buffer);
360 if (!(lineset->selection & FREESTYLE_SEL_EDGE_TYPES) || !lineset->edge_types) {
361 ++use_ridges_and_valleys;
362 ++use_suggestive_contours;
363 ++use_material_boundaries;
364 }
365 else {
366 // conditions for feature edge selection by edge types
367 for (int i = 0; i < num_edge_types; i++) {
368 if (!(lineset->edge_types & conditions[i].edge_type)) {
369 conditions[i].value = 0; // no condition specified
370 }
371 else if (!(lineset->exclude_edge_types & conditions[i].edge_type)) {
372 conditions[i].value = 1; // condition: X
373 }
374 else {
375 conditions[i].value = -1; // condition: NOT X
376 }
377 }
378 // logical operator for the selection conditions
379 bool logical_and = ((lineset->flags & FREESTYLE_LINESET_FE_AND) != 0);
380 // negation operator
381 if (lineset->flags & FREESTYLE_LINESET_FE_NOT) {
382 // convert an Exclusive condition into an
383 // Inclusive equivalent using De Morgan's laws:
384 // - NOT (X OR Y) --> (NOT X) AND (NOT Y)
385 // - NOT (X AND Y) --> (NOT X) OR (NOT Y)
386 for (int i = 0; i < num_edge_types; i++) {
387 conditions[i].value *= -1;
388 }
389 logical_and = !logical_and;
390 }
392 conditions, num_edge_types, logical_and, FREESTYLE_FE_RIDGE_VALLEY, true))
393 {
394 ++use_ridges_and_valleys;
395 }
396 if (test_edge_type_conditions(conditions,
397 num_edge_types,
398 logical_and,
400 true))
401 {
402 ++use_suggestive_contours;
403 }
405 conditions, num_edge_types, logical_and, FREESTYLE_FE_MATERIAL_BOUNDARY, true))
406 {
407 ++use_material_boundaries;
408 }
409 }
410 layer_count++;
411 }
412 }
413 controller->setComputeRidgesAndValleysFlag(use_ridges_and_valleys > 0);
414 controller->setComputeSuggestiveContoursFlag(use_suggestive_contours > 0);
415 controller->setComputeMaterialBoundariesFlag(use_material_boundaries > 0);
416 break;
417 }
418
419 // set parameters
427
428 if (G.debug & G_DEBUG_FREESTYLE) {
429 cout << "Crease angle : " << controller->getCreaseAngle() << endl;
430 cout << "Sphere radius : " << controller->getSphereRadius() << endl;
431 cout << "Face smoothness : " << (controller->getFaceSmoothness() ? "enabled" : "disabled")
432 << endl;
433 cout << "Ridges and valleys : "
434 << (controller->getComputeRidgesAndValleysFlag() ? "enabled" : "disabled") << endl;
435 cout << "Suggestive contours : "
436 << (controller->getComputeSuggestiveContoursFlag() ? "enabled" : "disabled") << endl;
437 cout << "Suggestive contour Kr derivative epsilon : "
439 cout << "Material boundaries : "
440 << (controller->getComputeMaterialBoundariesFlag() ? "enabled" : "disabled") << endl;
441 cout << endl;
442 }
443
444 // set diffuse and z depth passes
445 RenderLayer *rl = RE_GetRenderLayer(re->result, view_layer->name);
446 bool diffuse = false, z = false;
447 LISTBASE_FOREACH (RenderPass *, rpass, &rl->passes) {
448 float *rpass_buffer_data = rpass->ibuf->float_buffer.data;
449 if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE_COLOR)) {
450 controller->setPassDiffuse(rpass_buffer_data, rpass->rectx, rpass->recty);
451 diffuse = true;
452 }
453 if (STREQ(rpass->name, RE_PASSNAME_Z)) {
454 controller->setPassZ(rpass_buffer_data, rpass->rectx, rpass->recty);
455 z = true;
456 }
457 }
458 if (G.debug & G_DEBUG_FREESTYLE) {
459 cout << "Passes :" << endl;
460 cout << " Diffuse = " << (diffuse ? "enabled" : "disabled") << endl;
461 cout << " Z = " << (z ? "enabled" : "disabled") << endl;
462 }
463
465 return;
466 }
467
468 // compute view map
469 re->i.infostr = RPT_("Freestyle: View map creation");
470 re->stats_draw(&re->i);
471 re->i.infostr = nullptr;
473}
474
475void FRS_composite_result(Render *re, ViewLayer *view_layer, Render *freestyle_render)
476{
477 RenderLayer *rl;
478 float *src, *dest, *pixSrc, *pixDest;
479 int x, y, rectx, recty;
480
481 if (freestyle_render == nullptr || freestyle_render->result == nullptr) {
483 // Create a blank render pass output.
485 re->result, RE_PASSNAME_FREESTYLE, 4, "RGBA", view_layer->name, re->viewname, true);
486 }
487 return;
488 }
489
490 rl = render_get_single_layer(freestyle_render, freestyle_render->result);
491 if (!rl) {
492 if (G.debug & G_DEBUG_FREESTYLE) {
493 cout << "No source render layer to composite" << endl;
494 }
495 return;
496 }
497
498 src = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, freestyle_render->viewname);
499 if (!src) {
500 if (G.debug & G_DEBUG_FREESTYLE) {
501 cout << "No source result image to composite" << endl;
502 }
503 return;
504 }
505#if 0
506 if (G.debug & G_DEBUG_FREESTYLE) {
507 cout << "src: " << rl->rectx << " x " << rl->recty << endl;
508 }
509#endif
510
511 rl = RE_GetRenderLayer(re->result, view_layer->name);
512 if (!rl) {
513 if (G.debug & G_DEBUG_FREESTYLE) {
514 cout << "No destination render layer to composite to" << endl;
515 }
516 return;
517 }
518
521 re->result, RE_PASSNAME_FREESTYLE, 4, "RGBA", view_layer->name, re->viewname, true);
523 }
524 else {
526 }
527 if (!dest) {
528 if (G.debug & G_DEBUG_FREESTYLE) {
529 cout << "No destination result image to composite to" << endl;
530 }
531 return;
532 }
533#if 0
534 if (G.debug & G_DEBUG_FREESTYLE) {
535 cout << "dest: " << rl->rectx << " x " << rl->recty << endl;
536 }
537#endif
538
539 rectx = re->rectx;
540 recty = re->recty;
541 for (y = 0; y < recty; y++) {
542 for (x = 0; x < rectx; x++) {
543 pixSrc = src + 4 * (rectx * y + x);
544 if (pixSrc[3] > 0.0) {
545 pixDest = dest + 4 * (rectx * y + x);
546 blend_color_mix_float(pixDest, pixDest, pixSrc);
547 }
548 }
549 }
550}
551
552static int displayed_layer_count(ViewLayer *view_layer)
553{
554 int count = 0;
555
556 switch (view_layer->freestyle_config.mode) {
559 if (module->script && module->is_displayed) {
560 count++;
561 }
562 }
563 break;
566 if (lineset->flags & FREESTYLE_LINESET_ENABLED) {
567 count++;
568 }
569 }
570 break;
571 }
572 return count;
573}
574
576{
577 return ((view_layer->flag & VIEW_LAYER_RENDER) && (view_layer->flag & VIEW_LAYER_FREESTYLE) &&
578 displayed_layer_count(view_layer) > 0);
579}
580
582{
583 if (G.debug & G_DEBUG_FREESTYLE) {
584 cout << endl;
585 cout << "#===============================================================" << endl;
586 cout << "# Freestyle" << endl;
587 cout << "#===============================================================" << endl;
588 }
589
590 init_view(re);
591
593}
594
596
598{
599 RenderMonitor monitor(re);
600 controller->setRenderMonitor(&monitor);
602 (view_layer->freestyle_config.flags & FREESTYLE_VIEW_MAP_CACHE) ? true : false);
603
604 if (G.debug & G_DEBUG_FREESTYLE) {
605 cout << endl;
606 cout << "----------------------------------------------------------" << endl;
607 cout << "| " << (re->scene->id.name + 2) << "|" << view_layer->name << endl;
608 cout << "----------------------------------------------------------" << endl;
609 }
610
611 /* Create depsgraph and evaluate scene. */
612 ViewLayer *scene_view_layer = (ViewLayer *)BLI_findstring(
613 &re->scene->view_layers, view_layer->name, offsetof(ViewLayer, name));
614 Depsgraph *depsgraph = DEG_graph_new(re->main, re->scene, scene_view_layer, DAG_EVAL_RENDER);
616
617 /* Init camera
618 * Objects are transformed into camera coordinate system, therefore the camera position
619 * is zero and the modelview matrix is the identity matrix. */
620 Object *ob_camera_orig = RE_GetCamera(re);
621 Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, ob_camera_orig);
624 RE_GetCameraWindow(re, ob_camera_eval, g_freestyle.proj);
625
626 // prepare Freestyle:
627 // - load mesh
628 // - add style modules
629 // - set parameters
630 // - compute view map
631 prepare(re, view_layer, depsgraph);
632
633 if (re->test_break()) {
635 if (G.debug & G_DEBUG_FREESTYLE) {
636 cout << "Break" << endl;
637 }
638 }
639 else {
640 // render and composite Freestyle result
641 if (controller->_ViewMap) {
642 // render strokes
643 re->i.infostr = RPT_("Freestyle: Stroke rendering");
644 re->stats_draw(&re->i);
645 re->i.infostr = nullptr;
647 int strokeCount = controller->DrawStrokes();
648 Render *freestyle_render = nullptr;
649 if (strokeCount > 0) {
650 freestyle_render = controller->RenderStrokes(re, true);
651 }
653 g_freestyle.scene = nullptr;
654
655 // composite result
656 FRS_composite_result(re, view_layer, freestyle_render);
657 if (freestyle_render) {
658 RE_FreeRender(freestyle_render);
659 }
660 }
661 }
662
664}
665
667{
668 // clear canvas
669 controller->Clear();
670}
671
673{
674 // free cache
676#if 0
677 if (G.debug & G_DEBUG_FREESTYLE) {
678 printf("View map cache freed\n");
679 }
680#endif
681}
682
683//=======================================================
684// Freestyle Panel Configuration
685//=======================================================
686
688{
690
691 if (lineset) {
693 lineset_buffer.flags = lineset->flags;
695 lineset_buffer.qi = lineset->qi;
697 lineset_buffer.qi_end = lineset->qi_end;
700 lineset_buffer.group = lineset->group;
701 STRNCPY(lineset_buffer.name, lineset->name);
702 lineset_copied = true;
703 }
704}
705
707{
708 if (!lineset_copied) {
709 return;
710 }
711
713
714 if (lineset) {
715 if (lineset->linestyle) {
716 id_us_min(&lineset->linestyle->id);
717 }
719 if (lineset->linestyle) {
720 id_us_plus(&lineset->linestyle->id);
721 }
722 lineset->flags = lineset_buffer.flags;
724 lineset->qi = lineset_buffer.qi;
726 lineset->qi_end = lineset_buffer.qi_end;
729 if (lineset->group) {
730 id_us_min(&lineset->group->id);
731 lineset->group = nullptr;
732 }
733 if (lineset_buffer.group) {
734 lineset->group = lineset_buffer.group;
735 id_us_plus(&lineset->group->id);
736 }
737 STRNCPY(lineset->name, lineset_buffer.name);
738 BKE_freestyle_lineset_unique_name(config, lineset);
740 }
741}
742
744{
746
747 if (lineset) {
748 BKE_freestyle_lineset_delete(config, lineset);
749 }
750}
751
752bool FRS_move_active_lineset(FreestyleConfig *config, int direction)
753{
755 return (lineset != nullptr) && BLI_listbase_link_move(&config->linesets, lineset, direction);
756}
757
758// Testing
759
761{
762 bNodeTree *nt = (linestyle->use_nodes) ? linestyle->nodetree : nullptr;
764 ma->id.us = 0;
765 return ma;
766}
767
768} // extern "C"
Configuration file.
void BKE_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt)
Definition callbacks.cc:75
@ BKE_CB_EVT_LOAD_POST
Scene * CTX_data_scene(const bContext *C)
bool BKE_freestyle_lineset_delete(struct FreestyleConfig *config, struct FreestyleLineSet *lineset)
Definition freestyle.cc:195
void BKE_freestyle_lineset_unique_name(struct FreestyleConfig *config, struct FreestyleLineSet *lineset)
Definition freestyle.cc:148
struct FreestyleLineSet * BKE_freestyle_lineset_get_active(struct FreestyleConfig *config)
Definition freestyle.cc:212
@ G_DEBUG_FREESTYLE
void id_us_plus(ID *id)
Definition lib_id.cc:351
void id_us_min(ID *id)
Definition lib_id.cc:359
Blender kernel freestyle line style functionality.
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
Definition scene.cc:2647
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
Definition listbase.cc:435
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
void unit_m4(float m[4][4])
Definition rct.c:1127
#define RAD2DEGF(_rad)
MINLINE void zero_v3(float r[3])
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define ARRAY_SIZE(arr)
#define STREQ(a, b)
#define RPT_(msgid)
The spinal tap of the system.
@ DAG_EVAL_RENDER
Depsgraph * DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
Definition depsgraph.cc:273
void DEG_graph_free(Depsgraph *graph)
Definition depsgraph.cc:301
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object groups, one object can be in many groups at once.
@ FREESTYLE_CONTROL_EDITOR_MODE
@ FREESTYLE_CONTROL_SCRIPT_MODE
@ FREESTYLE_LINESET_FE_AND
@ FREESTYLE_LINESET_ENABLED
@ FREESTYLE_LINESET_CURRENT
@ FREESTYLE_LINESET_FE_NOT
@ FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE
@ FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE
@ FREESTYLE_FE_EDGE_MARK
@ FREESTYLE_FE_BORDER
@ FREESTYLE_FE_SILHOUETTE
@ FREESTYLE_FE_RIDGE_VALLEY
@ FREESTYLE_FE_CREASE
@ FREESTYLE_FE_EXTERNAL_CONTOUR
@ FREESTYLE_FE_CONTOUR
@ FREESTYLE_FE_SUGGESTIVE_CONTOUR
@ FREESTYLE_FE_MATERIAL_BOUNDARY
@ FREESTYLE_SEL_EDGE_TYPES
@ FREESTYLE_CULLING
@ FREESTYLE_FACE_SMOOTHNESS_FLAG
@ FREESTYLE_MATERIAL_BOUNDARIES_FLAG
@ FREESTYLE_RIDGES_AND_VALLEYS_FLAG
@ FREESTYLE_VIEW_MAP_CACHE
@ FREESTYLE_SUGGESTIVE_CONTOURS_FLAG
@ FREESTYLE_AS_RENDER_PASS
@ VIEW_LAYER_FREESTYLE
@ VIEW_LAYER_RENDER
#define RE_PASSNAME_COMBINED
@ R_LINE_THICKNESS_ABSOLUTE
@ R_LINE_THICKNESS_RELATIVE
@ R_BORDER
#define RE_PASSNAME_DIFFUSE_COLOR
#define RE_PASSNAME_Z
#define RE_PASSNAME_FREESTYLE
static bool test_edge_type_conditions(edge_type_condition *conditions, int num_edge_types, bool logical_and, int target, bool distinct)
static char * escape_quotes(char *name)
void FRS_paste_active_lineset(FreestyleConfig *config)
static void load_post_callback(Main *, PointerRNA **, const int, void *)
void FRS_end_stroke_rendering(Render *)
static void prepare(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
void FRS_composite_result(Render *re, ViewLayer *view_layer, Render *freestyle_render)
int FRS_is_freestyle_enabled(ViewLayer *view_layer)
void FRS_init()
static void init_view(Render *re)
static bool lineset_copied
static int displayed_layer_count(ViewLayer *view_layer)
bool FRS_move_active_lineset(FreestyleConfig *config, int direction)
void FRS_delete_active_lineset(FreestyleConfig *config)
static bCallbackFuncStore load_post_callback_funcstore
static char * create_lineset_handler(char *layer_name, char *lineset_name)
static AppView * view
void FRS_free_view_map_cache()
void FRS_exit()
void FRS_init_stroke_renderer(Render *re)
Material * FRS_create_stroke_material(Main *bmain, FreestyleLineStyle *linestyle)
FreestyleGlobals g_freestyle
void FRS_begin_stroke_rendering(Render *)
void FRS_set_context(bContext *C)
static Controller * controller
static bool freestyle_is_initialized
static Config::Path * pathconfig
void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer)
void FRS_copy_active_lineset(FreestyleConfig *config)
static FreestyleLineSet lineset_buffer
Read Guarded memory(de)allocation.
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
static Material * GetStrokeShader(Main *bmain, bNodeTree *iNodeTree, bool do_id_user)
Render * RenderStrokes(Render *re, bool render)
void setComputeSuggestiveContoursFlag(bool b)
void setPassZ(float *buf, int width, int height)
bool getFaceSmoothness() const
bool getComputeMaterialBoundariesFlag() const
void setSphereRadius(float s)
Definition Controller.h:134
void setComputeMaterialBoundariesFlag(bool b)
void setVisibilityAlgo(int algo)
void setComputeRidgesAndValleysFlag(bool b)
void setFaceSmoothness(bool iBool)
void setPassDiffuse(float *buf, int width, int height)
float getSphereRadius() const
Definition Controller.h:138
void DeleteViewMap(bool freeCache=false)
int LoadMesh(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
bool getComputeSuggestiveContoursFlag() const
void setViewMapCache(bool iBool)
void toggleLayer(uint index, bool iDisplay)
void setContext(bContext *C)
void setSuggestiveContourKrDerivativeEpsilon(float dkr)
Definition Controller.h:142
void setCreaseAngle(float angle)
Definition Controller.h:126
float getCreaseAngle() const
Definition Controller.h:130
bool getComputeRidgesAndValleysFlag() const
float getSuggestiveContourKrDerivativeEpsilon() const
Definition Controller.h:146
void setView(AppView *iView)
void setRenderMonitor(RenderMonitor *iRenderMonitor)
void InsertStyleModule(uint index, const char *iFileName)
std::string id_name(void *id)
#define printf
FreestyleLineStyle linestyle
const Depsgraph * depsgraph
#define offsetof(t, d)
void RE_GetCameraWindow(Render *re, const Object *camera, float r_winmat[4][4])
Object * RE_GetCamera(Render *re)
int count
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define G(x, y, z)
inherits from class Rep
Definition AppCanvas.cpp:20
static uint x[3]
Definition RandGen.cpp:77
static struct PyModuleDef module
Definition python.cpp:991
void RE_create_render_pass(RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname, const bool allocate)
void RE_FreeRender(Render *re)
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
float * RE_RenderLayerGetPass(RenderLayer *rl, const char *name, const char *viewname)
RenderLayer * render_get_single_layer(Render *re, RenderResult *rr)
RenderResult * result
float proj[4][4]
struct Scene * scene
struct Collection * group
struct FreestyleLineStyle * linestyle
struct bNodeTree * nodetree
int us
Definition DNA_ID.h:435
char name[66]
Definition DNA_ID.h:425
float unit_line_thickness
ListBase passes
Definition RE_pipeline.h:97
const char * infostr
bool test_break() override
RenderData r
struct Main * main
Scene * scene
char viewname[MAX_NAME]
RenderStats i
rcti disprect
void stats_draw(RenderStats *render_stats) override
struct RenderData r
ListBase view_layers
struct FreestyleConfig freestyle_config
char name[64]
int ymin
int ymax
int xmin
int xmax