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