diff options
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h')
-rw-r--r-- | source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h | 155 |
1 files changed, 94 insertions, 61 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 1239deb95bb..861085d3e16 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -23,6 +23,7 @@ #pragma once +#include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_math.h" /* Needed here for inline functions. */ #include "BLI_threads.h" @@ -93,8 +94,8 @@ typedef struct LineartElementLinkNode { float crease_threshold; } LineartElementLinkNode; -typedef struct LineartLineSegment { - struct LineartLineSegment *next, *prev; +typedef struct LineartEdgeSegment { + struct LineartEdgeSegment *next, *prev; /** at==0: left at==1: right (this is in 2D projected space) */ double at; /** Occlusion level after "at" point */ @@ -107,7 +108,7 @@ typedef struct LineartLineSegment { * enough for most cases. */ unsigned char transparency_mask; -} LineartLineSegment; +} LineartEdgeSegment; typedef struct LineartVert { double gloc[3]; @@ -155,7 +156,7 @@ typedef struct LineartEdge { /** * Still need this entry because culled lines will not add to object - * #LineartElementLinkNode node (known as `reln` internally). + * #LineartElementLinkNode node (known as `eln` internally). * * TODO: If really need more savings, we can allocate this in a "extended" way too, but we need * another bit in flags to be able to show the difference. @@ -163,8 +164,8 @@ typedef struct LineartEdge { struct Object *object_ref; } LineartEdge; -typedef struct LineartLineChain { - struct LineartLineChain *next, *prev; +typedef struct LineartEdgeChain { + struct LineartEdgeChain *next, *prev; ListBase chain; /** Calculated before draw command. */ @@ -179,10 +180,10 @@ typedef struct LineartLineChain { unsigned char transparency_mask; struct Object *object_ref; -} LineartLineChain; +} LineartEdgeChain; -typedef struct LineartLineChainItem { - struct LineartLineChainItem *next, *prev; +typedef struct LineartEdgeChainItem { + struct LineartEdgeChainItem *next, *prev; /** Need z value for fading */ float pos[3]; /** For restoring position to 3d space */ @@ -192,12 +193,12 @@ typedef struct LineartLineChainItem { char occlusion; unsigned char transparency_mask; size_t index; -} LineartLineChainItem; +} LineartEdgeChainItem; typedef struct LineartChainRegisterEntry { struct LineartChainRegisterEntry *next, *prev; - LineartLineChain *rlc; - LineartLineChainItem *rlci; + LineartEdgeChain *ec; + LineartEdgeChainItem *eci; char picked; /* left/right mark. @@ -205,6 +206,17 @@ typedef struct LineartChainRegisterEntry { char is_left; } LineartChainRegisterEntry; +enum eLineArtTileRecursiveLimit { + /* If tile gets this small, it's already much smaller than a pixel. No need to continue + * splitting. */ + LRT_TILE_RECURSIVE_PERSPECTIVE = 30, + /* This is a tried-and-true safe value for high poly models that also needed ortho rendering. */ + LRT_TILE_RECURSIVE_ORTHO = 10, +}; + +#define LRT_TILE_SPLITTING_TRIANGLE_LIMIT 100 +#define LRT_TILE_EDGE_COUNT_INITIAL 32 + typedef struct LineartRenderBuffer { struct LineartRenderBuffer *prev, *next; @@ -215,10 +227,16 @@ typedef struct LineartRenderBuffer { int tile_count_x, tile_count_y; double width_per_tile, height_per_tile; double view_projection[4][4]; + double view[4][4]; struct LineartBoundingArea *initial_bounding_areas; unsigned int bounding_area_count; + /* When splitting bounding areas, if there's an ortho camera placed at a straight angle, there + * will be a lot of triangles aligned in line which can not be separated by continue subdividing + * the tile. So we set a strict limit when using ortho camera. See eLineArtTileRecursiveLimit. */ + int tile_recursive_level; + ListBase vertex_buffer_pointers; ListBase line_buffer_pointers; ListBase triangle_buffer_pointers; @@ -237,31 +255,14 @@ typedef struct LineartRenderBuffer { int triangle_size; - unsigned int contour_count; - unsigned int contour_processed; - LineartEdge *contour_managed; - /** A single linked list (cast to #LinkNode). */ - LineartEdge *contours; - - unsigned int intersection_count; - unsigned int intersection_processed; - LineartEdge *intersection_managed; - LineartEdge *intersection_lines; - - unsigned int crease_count; - unsigned int crease_processed; - LineartEdge *crease_managed; - LineartEdge *crease_lines; - - unsigned int material_line_count; - unsigned int material_processed; - LineartEdge *material_managed; - LineartEdge *material_lines; - - unsigned int edge_mark_count; - unsigned int edge_mark_processed; - LineartEdge *edge_mark_managed; - LineartEdge *edge_marks; + /* Although using ListBase here, LineartEdge is single linked list. + * list.last is used to store worker progress along the list. + * See lineart_main_occlusion_begin() for more info. */ + ListBase contour; + ListBase intersection; + ListBase crease; + ListBase material; + ListBase edge_mark; ListBase chains; @@ -311,7 +312,7 @@ typedef struct LineartRenderBuffer { #define DBL_TRIANGLE_LIM 1e-8 #define DBL_EDGE_LIM 1e-9 -#define LRT_MEMORY_POOL_64MB (1 << 26) +#define LRT_MEMORY_POOL_1MB (1 << 20) typedef enum eLineartTriangleFlags { LRT_CULL_DONT_CARE = 0, @@ -322,9 +323,11 @@ typedef enum eLineartTriangleFlags { LRT_TRIANGLE_NO_INTERSECTION = (1 << 4), } eLineartTriangleFlags; -/** Controls how many edges a worker thread is processing at one request. +/** + * Controls how many edges a worker thread is processing at one request. * There's no significant performance impact on choosing different values. - * Don't make it too small so that the worker thread won't request too many times. */ + * Don't make it too small so that the worker thread won't request too many times. + */ #define LRT_THREAD_EDGE_COUNT 1000 typedef struct LineartRenderTaskInfo { @@ -332,23 +335,51 @@ typedef struct LineartRenderTaskInfo { int thread_id; - LineartEdge *contour; - LineartEdge *contour_end; - - LineartEdge *intersection; - LineartEdge *intersection_end; - - LineartEdge *crease; - LineartEdge *crease_end; - - LineartEdge *material; - LineartEdge *material_end; - - LineartEdge *edge_mark; - LineartEdge *edge_mark_end; + /* These lists only denote the part of the main edge list that the thread should iterate over. + * Be careful to not iterate outside of these bounds as it is not thread safe to do so. */ + ListBase contour; + ListBase intersection; + ListBase crease; + ListBase material; + ListBase edge_mark; } LineartRenderTaskInfo; +struct BMesh; + +typedef struct LineartObjectInfo { + struct LineartObjectInfo *next; + struct Object *original_ob; + struct Mesh *original_me; + double model_view_proj[4][4]; + double model_view[4][4]; + double normal[4][4]; + LineartElementLinkNode *v_reln; + int usage; + int global_i_offset; + + bool free_use_mesh; + + /* Threads will add lines inside here, when all threads are done, we combine those into the + * ones in LineartRenderBuffer. */ + ListBase contour; + ListBase intersection; + ListBase crease; + ListBase material; + ListBase edge_mark; + ListBase floating; + +} LineartObjectInfo; + +typedef struct LineartObjectLoadTaskInfo { + struct LineartRenderBuffer *rb; + struct Depsgraph *dg; + /* LinkNode styled list */ + LineartObjectInfo *pending; + /* Used to spread the load across several threads. This can not overflow. */ + long unsigned int total_faces; +} LineartObjectLoadTaskInfo; + /** * Bounding area diagram: * \code{.txt} @@ -385,10 +416,14 @@ typedef struct LineartBoundingArea { ListBase up; ListBase bp; - short triangle_count; + int16_t triangle_count; + int16_t max_triangle_count; + int16_t line_count; + int16_t max_line_count; - ListBase linked_triangles; - ListBase linked_lines; + /* Use array for speeding up multiple accesses. */ + struct LineartTriangle **linked_triangles; + struct LineartEdge **linked_lines; /** Reserved for image space reduction && multi-thread chaining. */ ListBase linked_chains; @@ -527,7 +562,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb); void MOD_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold); void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad); -int MOD_lineart_chain_count(const LineartLineChain *rlc); +int MOD_lineart_chain_count(const LineartEdgeChain *ec); void MOD_lineart_chain_clear_picked_flag(struct LineartRenderBuffer *rb); bool MOD_lineart_compute_feature_lines(struct Depsgraph *depsgraph, @@ -543,7 +578,6 @@ LineartBoundingArea *MOD_lineart_get_bounding_area(LineartRenderBuffer *rb, doub struct bGPDlayer; struct bGPDframe; -struct GpencilModifierData; void MOD_lineart_gpencil_generate(LineartRenderBuffer *rb, struct Depsgraph *depsgraph, @@ -560,11 +594,10 @@ void MOD_lineart_gpencil_generate(LineartRenderBuffer *rb, unsigned char transparency_mask, short thickness, float opacity, - float resample_length, const char *source_vgname, const char *vgname, int modifier_flags); -float MOD_lineart_chain_compute_length(LineartLineChain *rlc); +float MOD_lineart_chain_compute_length(LineartEdgeChain *ec); void ED_operatortypes_lineart(void); |