Blender V4.3
MOD_lineart.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include "BLI_linklist.h"
12#include "BLI_listbase.h"
14#include "BLI_math_vector.h"
15#include "BLI_set.hh"
16#include "BLI_threads.h"
17
18#include "ED_grease_pencil.hh"
19
20#include <algorithm>
21#include <math.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27typedef struct LineartModifierRuntime {
28 /* This list is constructed during `update_depsgraph()` call, and stays valid until the next
29 * update. This way line art can load objects from this list instead of iterating over all
30 * objects that may or may not have finished evaluating. */
31 std::unique_ptr<blender::Set<const Object *>> object_dependencies;
33
36 size_t size;
37 size_t used_byte;
38 /* User memory starts here */
40
45
49
50typedef struct LineartTriangle {
51 struct LineartVert *v[3];
52
53 /* first culled in line list to use adjacent triangle info, then go through triangle list. */
54 double gn[3];
55
59 uint8_t flags; /* #eLineartTriangleFlags */
60
61 /* target_reference = (obi->obindex | triangle_index) */
62 /* higher 12 bits-------^ ^-----index in object, lower 20 bits */
64
66
74
87
95
96typedef struct LineartElementLinkNode {
98 void *pointer;
102
103 /* For edge element link nodes, used for shadow edge matching. */
106
110
111typedef struct LineartEdgeSegment {
115 double ratio;
118
119 /* Used to filter line art occlusion edges */
121
122 /* Lit/shaded flag for shadow is stored here.
123 * TODO(Yiming): Transfer material masks from shadow results
124 * onto here so then we can even filter transparent shadows. */
127
128typedef struct LineartShadowEdge {
130 /* Two end points in frame-buffer coordinates viewed from the light source. */
131 double fbc1[4], fbc2[4];
132 double g1[3], g2[3];
136 struct LineartEdgeSegment *es_ref; /* Only for 3rd stage casting. */
139
144
145/* Represents a cutting point on a #LineartShadowEdge */
146typedef struct LineartShadowSegment {
148 /* eLineartShadowSegmentFlag */
149 int flag;
150 /* The point after which a property of the segment is changed. e.g. shadow mask/target_ref etc.
151 * Coordinates in NDC during shadow calculation but transformed to global linear before cutting
152 * onto edges during the loading stage of the "actual" rendering. */
153 double ratio;
154 /* Left and right pos, because when casting shadows at some point there will be
155 * non-continuous cuts, see #lineart_shadow_edge_cut for detailed explanation. */
156 double fbc1[4], fbc2[4];
157 /* Global position. */
158 double g1[4], g2[4];
162
163typedef struct LineartVert {
164 double gloc[3];
165 double fbcoord[4];
166
167 /* Scene global index. */
168 int index;
170
210
211typedef struct LineartEdgeChain {
214
216 float length;
217
221
223 int type;
229
230 /* We need local index for correct weight transfer, line art index is global, thus
231 * local_index=lineart_index-index_offset. */
233
237
252
258
259 /* left/right mark.
260 * Because we revert list in chaining so we need the flag. */
263
269
271 /* If tile gets this small, it's already much smaller than a pixel. No need to continue
272 * splitting. */
274 /* This is a tried-and-true safe value for high poly models that also needed ortho rendering. */
276};
277
278#define LRT_TILE_SPLITTING_TRIANGLE_LIMIT 100
279#define LRT_TILE_EDGE_COUNT_INITIAL 32
280
285
291
292typedef struct LineartData {
293
294 int w, h;
297
299 /* A pointer to LineartCache::chain_data_pool, which acts as a cache for edge chains. */
301 /* Reference to LineartCache::shadow_data_pool, stay available until the final round of line art
302 * calculation is finished. */
304
305 /* Storing shadow edge eln, array, and cuts for shadow information, so it's available when line
306 * art runs the second time for occlusion. Either a reference to LineartCache::shadow_data_pool
307 * (shadow stage) or a reference to LineartData::render_data_pool (final stage). */
309
310 struct _qtree {
311
314
315 /* When splitting bounding areas, if there's an ortho camera placed at a straight angle, there
316 * will be a lot of triangles aligned in line which can not be separated by continue
317 * subdividing the tile. So we set a strict limit when using ortho camera. See
318 * eLineArtTileRecursiveLimit. */
320
322
324
326
339
340 struct _conf {
341
342 double view_projection[4][4];
343 double view[4][4];
344
345 float overscan;
346
350
353
362 bool use_contour_secondary; /* From viewing camera, during shadow calculation. */
363
364 int shadow_selection; /* Needs to be numeric because it's not just on/off. */
367
379
384
387
389
392
393 /* Keep an copy of these data so when line art is running itself contained. */
395 /* "Secondary" ones are from viewing camera
396 * (as opposed to shadow camera), during shadow calculation. */
398 float cam_obmat[4][4];
400 double camera_pos[3];
402 double active_camera_pos[3]; /* Stroke offset calculation may use active or selected camera. */
405
409
411
412 double view_vector[3];
413 double view_vector_secondary[3]; /* For shadow. */
415
418
419 /* NOTE: Data inside #pending_edges are allocated with MEM_xxx call instead of in pool. */
422
423 /* Intermediate shadow results, list of LineartShadowEdge */
426
428
433
435
453
454#define DBL_TRIANGLE_LIM 1e-8
455#define DBL_EDGE_LIM 1e-9
456
457#define LRT_MEMORY_POOL_1MB (1 << 20)
458
469
470#define LRT_SHADOW_MASK_UNDEFINED 0
471#define LRT_SHADOW_MASK_ILLUMINATED (1 << 0)
472#define LRT_SHADOW_MASK_SHADED (1 << 1)
473#define LRT_SHADOW_MASK_ENCLOSED_SHAPE (1 << 2)
474#define LRT_SHADOW_MASK_INHIBITED (1 << 3)
475#define LRT_SHADOW_SILHOUETTE_ERASED_GROUP (1 << 4)
476#define LRT_SHADOW_SILHOUETTE_ERASED_OBJECT (1 << 5)
477#define LRT_SHADOW_MASK_ILLUMINATED_SHAPE (1 << 6)
478
479#define LRT_SHADOW_TEST_SHAPE_BITS \
480 (LRT_SHADOW_MASK_ILLUMINATED | LRT_SHADOW_MASK_SHADED | LRT_SHADOW_MASK_INHIBITED | \
481 LRT_SHADOW_MASK_ILLUMINATED_SHAPE)
482
488#define LRT_THREAD_EDGE_COUNT 1000
489
502
503#define LRT_OBINDEX_SHIFT 20
504#define LRT_OBINDEX_LOWER 0x0FFFFF /* Lower 20 bits. */
505#define LRT_OBINDEX_HIGHER 0xFFF00000 /* Higher 12 bits. */
506#define LRT_EDGE_IDENTIFIER(obi, e) \
507 (((uint64_t)(obi->obindex | (e->v1->index & LRT_OBINDEX_LOWER)) << 32) | \
508 (obi->obindex | (e->v2->index & LRT_OBINDEX_LOWER)))
509#define LRT_LIGHT_CONTOUR_TARGET 0xFFFFFFFF
510
511typedef struct LineartObjectInfo {
514 struct Object *original_ob_eval; /* For evaluated materials */
516 double model_view_proj[4][4];
517 double model_view[4][4];
518 double normal[4][4];
520 int usage;
524
525 /* Shifted LRT_OBINDEX_SHIFT bits to be combined with object triangle index. */
527
529
532
534
538 /* LinkNode styled list */
540 /* Used to spread the load across several threads. This can not overflow. */
544
596
597#define LRT_TILE(tile, r, c, CCount) tile[r * CCount + c]
598
599#define LRT_CLAMP(a, Min, Max) a = a < Min ? Min : (a > Max ? Max : a)
600
601#define LRT_MAX3_INDEX(a, b, c) (a > b ? (a > c ? 0 : (b > c ? 1 : 2)) : (b > c ? 1 : 2))
602
603#define LRT_MIN3_INDEX(a, b, c) (a < b ? (a < c ? 0 : (b < c ? 1 : 2)) : (b < c ? 1 : 2))
604
605#define LRT_MAX3_INDEX_ABC(x, y, z) (x > y ? (x > z ? a : (y > z ? b : c)) : (y > z ? b : c))
606
607#define LRT_MIN3_INDEX_ABC(x, y, z) (x < y ? (x < z ? a : (y < z ? b : c)) : (y < z ? b : c))
608
609#define DBL_LOOSER 1e-5
610#define LRT_DOUBLE_CLOSE_LOOSER(a, b) (((a) + DBL_LOOSER) >= (b) && ((a)-DBL_LOOSER) <= (b))
611#define LRT_DOUBLE_CLOSE_ENOUGH(a, b) (((a) + DBL_EDGE_LIM) >= (b) && ((a)-DBL_EDGE_LIM) <= (b))
612#define LRT_DOUBLE_CLOSE_ENOUGH_TRI(a, b) \
613 (((a) + DBL_TRIANGLE_LIM) >= (b) && ((a)-DBL_TRIANGLE_LIM) <= (b))
614
615#define LRT_CLOSE_LOOSER_v3(a, b) \
616 (LRT_DOUBLE_CLOSE_LOOSER(a[0], b[0]) && LRT_DOUBLE_CLOSE_LOOSER(a[1], b[1]) && \
617 LRT_DOUBLE_CLOSE_LOOSER(a[2], b[2]))
618
619/* Notes on this function:
620 *
621 * r_ratio: The ratio on segment a1-a2. When r_ratio is very close to zero or one, it
622 * fixes the value to zero or one, this makes it easier to identify "on the tip" situations.
623 *
624 * r_aligned: True when 1) a and b is exactly on the same straight line and 2) a and b share a
625 * common end-point.
626 *
627 * IMPORTANT: if r_aligned is true, r_ratio will be either 0 or 1 depending on which point from
628 * segment a is shared with segment b. If it's a1 then r_ratio is 0, else then r_ratio is 1. This
629 * extra information is needed for line art occlusion stage to work correctly in such cases.
630 */
632 const double a2[2],
633 const double b1[2],
634 const double b2[2],
635 double *r_ratio,
636 bool *r_aligned)
637{
638/* Legacy intersection math aligns better with occlusion function quirks. */
639// #define USE_VECTOR_LINE_INTERSECTION
640#ifdef USE_VECTOR_LINE_INTERSECTION
641
642 /* from isect_line_line_v2_point() */
643
644 double s10[2], s32[2];
645 double div;
646
647 sub_v2_v2v2_db(s10, a2, a1);
648 sub_v2_v2v2_db(s32, b2, b1);
649
650 div = cross_v2v2_db(s10, s32);
651 if (div != 0.0f) {
652 const double u = cross_v2v2_db(a2, a1);
653 const double v = cross_v2v2_db(b2, b1);
654
655 const double rx = ((s32[0] * u) - (s10[0] * v)) / div;
656 const double ry = ((s32[1] * u) - (s10[1] * v)) / div;
657 double rr;
658
659 if (fabs(a2[0] - a1[0]) > fabs(a2[1] - a1[1])) {
660 *r_ratio = ratiod(a1[0], a2[0], rx);
661 if (fabs(b2[0] - b1[0]) > fabs(b2[1] - b1[1])) {
662 rr = ratiod(b1[0], b2[0], rx);
663 }
664 else {
665 rr = ratiod(b1[1], b2[1], ry);
666 }
667 if ((*r_ratio) > 0 && (*r_ratio) < 1 && rr > 0 && rr < 1) {
668 return 1;
669 }
670 return 0;
671 }
672
673 *r_ratio = ratiod(a1[1], a2[1], ry);
674 if (fabs(b2[0] - b1[0]) > fabs(b2[1] - b1[1])) {
675 rr = ratiod(b1[0], b2[0], rx);
676 }
677 else {
678 rr = ratiod(b1[1], b2[1], ry);
679 }
680 if ((*r_ratio) > 0 && (*r_ratio) < 1 && rr > 0 && rr < 1) {
681 return 1;
682 }
683 return 0;
684 }
685 return 0;
686
687#else
688 double k1, k2;
689 double x;
690 double y;
691 double ratio;
692 double x_diff = (a2[0] - a1[0]);
693 double x_diff2 = (b2[0] - b1[0]);
694
695 *r_aligned = false;
696
697 if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff, 0)) {
698 if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
699 /* This means two segments are both vertical. */
700 if ((LRT_DOUBLE_CLOSE_ENOUGH(a2[0], b1[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a2[1], b1[1])) ||
701 (LRT_DOUBLE_CLOSE_ENOUGH(a2[0], b2[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a2[1], b2[1])))
702 {
703 *r_aligned = true;
704 *r_ratio = 1;
705 }
706 else if ((LRT_DOUBLE_CLOSE_ENOUGH(a1[0], b1[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a1[1], b1[1])) ||
707 (LRT_DOUBLE_CLOSE_ENOUGH(a1[0], b2[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a1[1], b2[1])))
708 {
709 *r_aligned = true;
710 *r_ratio = 0;
711 }
712 return 0;
713 }
714 double r2 = ratiod(b1[0], b2[0], a1[0]);
715 x = interpd(b2[0], b1[0], r2);
716 y = interpd(b2[1], b1[1], r2);
717 *r_ratio = ratio = ratiod(a1[1], a2[1], y);
718 }
719 else {
720 if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
721 ratio = ratiod(a1[0], a2[0], b1[0]);
722 x = interpd(a2[0], a1[0], ratio);
723 *r_ratio = ratio;
724 }
725 else {
726 double y_diff = a2[1] - a1[1], y_diff2 = b2[1] - b1[1];
727 k1 = y_diff / x_diff;
728 k2 = y_diff2 / x_diff2;
729
730 if (LRT_DOUBLE_CLOSE_ENOUGH_TRI(k2, k1)) {
731 /* This means two segments are parallel. This also handles k==0 (both completely
732 * horizontal) cases. */
733 if ((LRT_DOUBLE_CLOSE_ENOUGH(a2[0], b1[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a2[1], b1[1])) ||
734 (LRT_DOUBLE_CLOSE_ENOUGH(a2[0], b2[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a2[1], b2[1])))
735 {
736 *r_aligned = true;
737 *r_ratio = 1;
738 }
739 else if ((LRT_DOUBLE_CLOSE_ENOUGH(a1[0], b1[0]) &&
740 LRT_DOUBLE_CLOSE_ENOUGH(a1[1], b1[1])) ||
741 (LRT_DOUBLE_CLOSE_ENOUGH(a1[0], b2[0]) && LRT_DOUBLE_CLOSE_ENOUGH(a1[1], b2[1])))
742 {
743 *r_aligned = true;
744 *r_ratio = 0;
745 }
746 return 0;
747 }
748
749 x = (a1[1] - b1[1] - k1 * a1[0] + k2 * b1[0]) / (k2 - k1);
750
751 ratio = (x - a1[0]) / x_diff;
752
753 *r_ratio = ratio;
754 }
755 }
756
757 if (LRT_DOUBLE_CLOSE_ENOUGH(b1[0], b2[0])) {
758 y = interpd(a2[1], a1[1], ratio);
759 if (y > std::max(b1[1], b2[1]) || y < std::min(b1[1], b2[1])) {
760 return 0;
761 }
762 }
763 else if (ratio <= 0 || ratio > 1 || (b1[0] > b2[0] && x > b1[0]) ||
764 (b1[0] < b2[0] && x < b1[0]) || (b2[0] > b1[0] && x > b2[0]) ||
765 (b2[0] < b1[0] && x < b2[0]))
766 {
767 return 0;
768 }
769
770 if (LRT_DOUBLE_CLOSE_ENOUGH_TRI(*r_ratio, 1)) {
771 *r_ratio = 1;
772 }
773 else if (LRT_DOUBLE_CLOSE_ENOUGH_TRI(*r_ratio, 0)) {
774 *r_ratio = 0;
775 }
776
777 return 1;
778#endif
779}
780
781/* This is a special convenience function to lineart_intersect_seg_seg which will return true when
782 * the intersection point falls in the range of a1-a2 but not necessarily in the range of b1-b2. */
784 const double a2[2],
785 const double b1[2],
786 const double b2[2],
787 double *r_a_ratio)
788{
789 /* The define here is used to check how vector or slope method handles boundary cases. The result
790 * of `lim(div->0)` and `lim(k->0)` could both produce some unwanted flickers in line art, the
791 * influence of which is still not fully understood, so keep the switch there for further
792 * investigations. */
793#define USE_VECTOR_LINE_INTERSECTION_IGN
794#ifdef USE_VECTOR_LINE_INTERSECTION_IGN
795
796 /* from isect_line_line_v2_point() */
797
798 double s10[2], s32[2];
799 double div;
800
801 sub_v2_v2v2_db(s10, a2, a1);
802 sub_v2_v2v2_db(s32, b2, b1);
803
804 div = cross_v2v2_db(s10, s32);
805 if (div != 0.0f) {
806 const double u = cross_v2v2_db(a2, a1);
807 const double v = cross_v2v2_db(b2, b1);
808
809 const double rx = ((s32[0] * u) - (s10[0] * v)) / div;
810 const double ry = ((s32[1] * u) - (s10[1] * v)) / div;
811
812 if (fabs(a2[0] - a1[0]) > fabs(a2[1] - a1[1])) {
813 *r_a_ratio = ratiod(a1[0], a2[0], rx);
814 if ((*r_a_ratio) >= -DBL_EDGE_LIM && (*r_a_ratio) <= 1 + DBL_EDGE_LIM) {
815 return 1;
816 }
817 return 0;
818 }
819
820 *r_a_ratio = ratiod(a1[1], a2[1], ry);
821 if ((*r_a_ratio) >= -DBL_EDGE_LIM && (*r_a_ratio) <= 1 + DBL_EDGE_LIM) {
822 return 1;
823 }
824 return 0;
825 }
826 return 0;
827
828#else
829 double k1, k2;
830 double x;
831 double y;
832 double ratio;
833 double x_diff = (a2[0] - a1[0]);
834 double x_diff2 = (b2[0] - b1[0]);
835
836 if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff, 0)) {
837 if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
838 *r_a_ratio = 0;
839 return 0;
840 }
841 double r2 = ratiod(b1[0], b2[0], a1[0]);
842 x = interpd(b2[0], b1[0], r2);
843 y = interpd(b2[1], b1[1], r2);
844 *r_a_ratio = ratio = ratiod(a1[1], a2[1], y);
845 }
846 else {
847 if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
848 ratio = ratiod(a1[0], a2[0], b1[0]);
849 x = interpd(a2[0], a1[0], ratio);
850 *r_a_ratio = ratio;
851 }
852 else {
853 k1 = (a2[1] - a1[1]) / x_diff;
854 k2 = (b2[1] - b1[1]) / x_diff2;
855
856 if ((k1 == k2))
857 return 0;
858
859 x = (a1[1] - b1[1] - k1 * a1[0] + k2 * b1[0]) / (k2 - k1);
860
861 ratio = (x - a1[0]) / x_diff;
862
863 *r_a_ratio = ratio;
864 }
865 }
866
867 if (ratio <= 0 || ratio >= 1)
868 return 0;
869
870 return 1;
871#endif
872}
873
874struct bGPDframe;
875struct bGPDlayer;
876struct Depsgraph;
879struct LineartData;
880struct Scene;
881
883
892void MOD_lineart_chain_discard_unused(LineartData *ld, float threshold, uint8_t max_occlusion);
898void MOD_lineart_chain_split_angle(LineartData *ld, float angle_threshold_rad);
899void MOD_lineart_smooth_chains(LineartData *ld, float tolerance);
900void MOD_lineart_chain_offset_towards_camera(LineartData *ld, float dist, bool use_custom_camera);
902
906
914 struct LineartCache **cached_result,
915 bool enable_stroke_depth_offset);
916
921
926
928class Drawing;
929}
931 const blender::float4x4 &mat,
932 Depsgraph *depsgraph,
934 int8_t source_type,
935 Object *source_object,
936 struct Collection *source_collection,
937 int level_start,
938 int level_end,
939 int mat_nr,
940 int16_t edge_types,
941 uchar mask_switches,
942 uchar material_mask_bits,
943 uchar intersection_mask,
944 float thickness,
945 float opacity,
946 uchar shadow_selection,
947 uchar silhouette_mode,
948 const char *source_vgname,
949 const char *vgname,
950 int modifier_flags,
951 int modifier_calculation_flags);
952
957
959void MOD_lineart_clear_cache(struct LineartCache **lc);
960
961#ifdef __cplusplus
962}
963#endif
#define BLI_INLINE
MINLINE double ratiod(double min, double max, double pos)
MINLINE double interpd(double target, double origin, double t)
MINLINE double cross_v2v2_db(const double a[2], const double b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2_db(double r[2], const double a[2], const double b[2])
unsigned char uchar
pthread_spinlock_t SpinLock
#define ENUM_OPERATORS(_type, _max)
LineartCache * MOD_lineart_init_cache()
void MOD_lineart_clear_cache(struct LineartCache **lc)
struct LineartStaticMemPool LineartStaticMemPool
bool MOD_lineart_compute_feature_lines_v3(struct Depsgraph *depsgraph, struct GreasePencilLineartModifierData &lmd, struct LineartCache **cached_result, bool enable_stroke_depth_offset)
struct LineartBoundingArea LineartBoundingArea
#define LRT_DOUBLE_CLOSE_ENOUGH(a, b)
#define LRT_DOUBLE_CLOSE_ENOUGH_TRI(a, b)
void MOD_lineart_chain_connect(LineartData *ld)
void MOD_lineart_chain_discard_unused(LineartData *ld, float threshold, uint8_t max_occlusion)
struct LineartCache LineartCache
struct LineartEdge LineartEdge
LineartBoundingArea * MOD_lineart_get_parent_bounding_area(LineartData *ld, double x, double y)
#define DBL_EDGE_LIM
float MOD_lineart_chain_compute_length(LineartEdgeChain *ec)
struct LineartRenderTaskInfo LineartRenderTaskInfo
BLI_INLINE int lineart_intersect_seg_seg(const double a1[2], const double a2[2], const double b1[2], const double b2[2], double *r_ratio, bool *r_aligned)
void MOD_lineart_chain_split_for_fixed_occlusion(LineartData *ld)
struct LineartEdgeChainItem LineartEdgeChainItem
struct LineartChainRegisterEntry LineartChainRegisterEntry
struct LineartObjectInfo LineartObjectInfo
void MOD_lineart_chain_clip_at_border(LineartData *ld)
struct LineartAdjacentEdge LineartAdjacentEdge
int MOD_lineart_chain_count(const LineartEdgeChain *ec)
struct LineartData LineartData
struct LineartPendingEdges LineartPendingEdges
void MOD_lineart_finalize_chains(LineartData *ld)
struct LineartEdgeChain LineartEdgeChain
struct LineartTriangleAdjacent LineartTriangleAdjacent
struct LineartStaticMemPoolNode LineartStaticMemPoolNode
eLineArtTileRecursiveLimit
@ LRT_TILE_RECURSIVE_PERSPECTIVE
@ LRT_TILE_RECURSIVE_ORTHO
void MOD_lineart_gpencil_generate_v3(const LineartCache *cache, const blender::float4x4 &mat, Depsgraph *depsgraph, blender::bke::greasepencil::Drawing &drawing, int8_t source_type, Object *source_object, struct Collection *source_collection, int level_start, int level_end, int mat_nr, int16_t edge_types, uchar mask_switches, uchar material_mask_bits, uchar intersection_mask, float thickness, float opacity, uchar shadow_selection, uchar silhouette_mode, const char *source_vgname, const char *vgname, int modifier_flags, int modifier_calculation_flags)
void MOD_lineart_chain_find_silhouette_backdrop_objects(LineartData *ld)
void MOD_lineart_destroy_render_data_v3(struct GreasePencilLineartModifierData *lmd)
LineartBoundingArea * MOD_lineart_get_bounding_area(LineartData *ld, double x, double y)
struct LineartEdgeSegment LineartEdgeSegment
struct LineartObjectLoadTaskInfo LineartObjectLoadTaskInfo
void MOD_lineart_chain_feature_lines(LineartData *ld)
struct LineartTriangleThread LineartTriangleThread
eLineartTriangleFlags
@ LRT_TRIANGLE_NO_INTERSECTION
@ LRT_CULL_GENERATED
@ LRT_CULL_DISCARD
@ LRT_TRIANGLE_MAT_BACK_FACE_CULLING
@ LRT_CULL_DONT_CARE
@ LRT_TRIANGLE_INTERSECTION_ONLY
@ LRT_TRIANGLE_FORCE_INTERSECTION
@ LRT_CULL_USED
struct LineartShadowEdge LineartShadowEdge
eLineArtElementNodeFlag
@ LRT_ELEMENT_NO_INTERSECTION
@ LRT_ELEMENT_BORDER_ONLY
@ LRT_ELEMENT_INTERSECTION_DATA
@ LRT_ELEMENT_IS_ADDITIONAL
void MOD_lineart_chain_clear_picked_flag(LineartCache *lc)
eLineartShadowCameraType
@ LRT_SHADOW_CAMERA_POINT
@ LRT_SHADOW_CAMERA_DIRECTIONAL
struct LineartElementLinkNode LineartElementLinkNode
struct LineartModifierRuntime LineartModifierRuntime
void MOD_lineart_smooth_chains(LineartData *ld, float tolerance)
BLI_INLINE int lineart_line_isec_2d_ignore_line2pos(const double a1[2], const double a2[2], const double b1[2], const double b2[2], double *r_a_ratio)
void MOD_lineart_chain_split_angle(LineartData *ld, float angle_threshold_rad)
eLineartShadowSegmentFlag
@ LRT_SHADOW_CASTED
@ LRT_SHADOW_FACING_LIGHT
void MOD_lineart_chain_offset_towards_camera(LineartData *ld, float dist, bool use_custom_camera)
struct LineartShadowSegment LineartShadowSegment
struct LineartTriangle LineartTriangle
struct LineartVert LineartVert
ATTR_WARN_UNUSED_RESULT const BMVert * v
const Depsgraph * depsgraph
ccl_device_inline float2 fabs(const float2 a)
signed short int16_t
Definition stdint.h:76
unsigned short uint16_t
Definition stdint.h:79
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
signed char int8_t
Definition stdint.h:75
struct LineartBoundingArea * child
struct LineartEdge ** linked_lines
uint32_t insider_triangle_count
struct LineartTriangle ** linked_triangles
uint32_t max_triangle_count
blender::ed::greasepencil::LineartLimitInfo LimitInfo
ListBase shadow_elns
ListBase chains
LineartStaticMemPool chain_data_pool
uint16_t all_enabled_edge_types
LineartStaticMemPool shadow_data_pool
struct LineartChainRegisterEntry * next
LineartEdgeChainItem * eci
struct LineartChainRegisterEntry * prev
LineartEdgeChain * ec
float cam_obmat_secondary[4][4]
double view_projection[4][4]
double view_vector_secondary[3]
double camera_pos_secondary[3]
bool filter_face_mark_keep_contour
double active_camera_pos[3]
float angle_splitting_threshold
float cam_obmat[4][4]
ListBase vertex_buffer_pointers
ListBase line_buffer_pointers
ListBase triangle_adjacent_pointers
ListBase intersecting_vertex_buffer
ListBase triangle_buffer_pointers
uint32_t initial_tile_count
struct LineartBoundingArea * initials
LineartShadowEdge * shadow_edges
ListBase wasted_shadow_cuts
LineartStaticMemPool render_data_pool
struct LineartData::_conf conf
struct LineartData::_geom geom
struct LineartData::_qtree qtree
int isect_scheduled_up_to_index
ListBase chains
LineartElementLinkNode * isect_scheduled_up_to
ListBase wasted_cuts
SpinLock lock_task
LineartStaticMemPool * edge_data_pool
SpinLock lock_cuts
struct LineartPendingEdges pending_edges
int shadow_edges_count
LineartStaticMemPool * shadow_data_pool
LineartStaticMemPool * chain_data_pool
struct LineartEdgeChainItem * next
struct LineartEdgeChainItem * prev
uint8_t material_mask_bits
uint32_t index_offset
struct Object * silhouette_backdrop
struct LineartEdgeChain * next
struct LineartEdgeChain * prev
uint32_t shadow_mask_bits
uint8_t intersection_mask
struct Object * object_ref
struct LineartEdgeSegment * prev
struct LineartEdgeSegment * next
uint32_t shadow_mask_bits
uint16_t flags
struct LineartVert * v2
ListBase segments
struct LineartTriangle * t2
uint64_t edge_identifier
uint8_t intersection_mask
struct LineartTriangle * t1
uint64_t target_reference
struct Object * object_ref
struct LineartVert * v1
eLineArtElementNodeFlag flags
struct LineartElementLinkNode * prev
struct LineartElementLinkNode * next
std::unique_ptr< blender::Set< const Object * > > object_dependencies
LineartElementLinkNode * v_eln
struct Mesh * original_me
double model_view[4][4]
struct LineartPendingEdges pending_edges
double model_view_proj[4][4]
struct Object * original_ob_eval
uint8_t override_intersection_mask
struct LineartObjectInfo * next
uint8_t intersection_priority
struct Object * original_ob
struct LineartData * ld
LineartObjectInfo * pending
LineartEdge ** array
struct LineartData * ld
struct LineartPendingEdges pending_edges
ListBase shadow_segments
struct LineartShadowEdge * prev
struct LineartEdgeSegment * es_ref
struct LineartShadowEdge * next
struct LineartEdge * e_ref_light_contour
struct LineartEdge * e_ref
struct LineartShadowSegment * next
struct LineartShadowSegment * prev
struct LineartEdge * e[3]
struct LineartEdge * testing_e[1]
struct LineartTriangle base
uint8_t material_mask_bits
uint8_t intersection_priority
uint8_t intersection_mask
uint32_t target_reference
struct LinkNode * intersecting_verts
uint8_t mat_occlusion
struct LineartVert * v[3]
double fbcoord[4]
double gloc[3]