Blender V4.3
mask_rasterize.cc File Reference
#include <algorithm>
#include "CLG_log.h"
#include "MEM_guardedalloc.h"
#include "DNA_mask_types.h"
#include "DNA_scene_types.h"
#include "DNA_vec_types.h"
#include "BLI_math_geom.h"
#include "BLI_math_vector.h"
#include "BLI_memarena.h"
#include "BLI_scanfill.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_task.h"
#include "BKE_mask.h"
#include "BLI_strict_flags.h"

Go to the source code of this file.

Classes

struct  MaskRasterLayer
 
struct  MaskRasterSplineInfo
 
struct  MaskRasterHandle
 
struct  MaskRasterizeBufferData
 

Macros

#define USE_SCANFILL_EDGE_WORKAROUND
 
#define SPLINE_RESOL_CAP_PER_PIXEL   2
 
#define SPLINE_RESOL_CAP_MIN   8
 
#define SPLINE_RESOL_CAP_MAX   64
 
#define BUCKET_PIXELS_PER_CELL   4
 
#define SF_EDGE_IS_BOUNDARY   0xff
 
#define SF_KEYINDEX_TEMP_ID   uint(-1)
 
#define TRI_TERMINATOR_ID   uint(-1)
 
#define TRI_VERT   uint(-1)
 
#define FACE_ASSERT(face, vert_max)
 
#define CALC_CAP_RESOL
 

Functions

static void rotate_point_v2 (float r_p[2], const float p[2], const float cent[2], const float angle, const float asp[2])
 
BLI_INLINE uint clampis_uint (const uint v, const uint min, const uint max)
 
static ScanFillVertscanfill_vert_add_v2_with_depth (ScanFillContext *sf_ctx, const float co_xy[2], const float co_z)
 
MaskRasterHandleBKE_maskrasterize_handle_new ()
 
void BKE_maskrasterize_handle_free (MaskRasterHandle *mr_handle)
 
static void maskrasterize_spline_differentiate_point_outset (float(*diff_feather_points)[2], float(*diff_points)[2], const uint tot_diff_point, const float ofs, const bool do_test)
 
static bool layer_bucket_isect_test (const MaskRasterLayer *layer, uint face_index, const uint bucket_x, const uint bucket_y, const float bucket_size_x, const float bucket_size_y, const float bucket_max_rad_squared)
 
static void layer_bucket_init_dummy (MaskRasterLayer *layer)
 
static void layer_bucket_init (MaskRasterLayer *layer, const float pixel_size)
 
void BKE_maskrasterize_handle_init (MaskRasterHandle *mr_handle, Mask *mask, const int width, const int height, const bool do_aspect_correct, const bool do_mask_aa, const bool do_feather)
 
static float maskrasterize_layer_z_depth_quad (const float pt[2], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
 
static float maskrasterize_layer_isect (const uint *face, float(*cos)[3], const float dist_orig, const float xy[2])
 
BLI_INLINE uint layer_bucket_index_from_xy (MaskRasterLayer *layer, const float xy[2])
 
static float layer_bucket_depth_from_xy (MaskRasterLayer *layer, const float xy[2])
 
float BKE_maskrasterize_handle_sample (MaskRasterHandle *mr_handle, const float xy[2])
 
static void maskrasterize_buffer_cb (void *__restrict userdata, const int y, const TaskParallelTLS *__restrict)
 
void BKE_maskrasterize_buffer (MaskRasterHandle *mr_handle, const uint width, const uint height, float *buffer)
 Rasterize a buffer from a single mask (threaded execution).
 

Variables

static CLG_LogRef LOG = {"bke.mask_rasterize"}
 

Detailed Description

This module exposes a rasterizer that works as a black box - implementation details are confined to this file.

The basic method to access is:

  • create & initialize a handle from a Mask datablock.
  • execute pixel lookups.
  • free the handle.

This file is admittedly a bit confusticated, in quite few areas speed was chosen over readability, though it is commented - so shouldn't be so hard to see what's going on.

Implementation:

To rasterize the mask its converted into geometry that use a ray-cast for each pixel lookup.

Initially 'kdopbvh' was used but this ended up being too slow.

To gain some extra speed we take advantage of a few shortcuts that can be made rasterizing masks specifically.

  • All triangles are known to be completely white - so no depth check is done on triangle intersection.
  • All quads are known to be feather outlines - the 1 and 0 depths are known by the vertex order in the quad,
  • There is no color - just a value for each mask pixel.
  • The mask spacial structure always maps to space 0-1 on X and Y axis.
  • Bucketing is used to speed up lookups for geometry.

Other Details:

  • used unsigned values all over for some extra speed on some arch's.
  • anti-aliasing is faked, just ensuring at least one pixel feather - avoids oversampling.
  • initializing the spacial structure doesn't need to be as optimized as pixel lookups are.
  • mask lookups need not be pixel aligned so any sub-pixel values from x/y (0 - 1), can be found. (perhaps masks can be used as a vector texture in 3D later on) Currently, to build the spacial structure we have to calculate the total number of faces ahead of time.

This is getting a bit complicated with the addition of unfilled splines and end capping - If large changes are needed here we would be better off using an iterable BLI_mempool for triangles and converting to a contiguous array afterwards.

Definition in file mask_rasterize.cc.

Macro Definition Documentation

◆ BUCKET_PIXELS_PER_CELL

#define BUCKET_PIXELS_PER_CELL   4

Definition at line 85 of file mask_rasterize.cc.

Referenced by layer_bucket_init().

◆ CALC_CAP_RESOL

#define CALC_CAP_RESOL
Value:
clampis_uint(uint(len_v2v2(fp_cent, fp_turn) / (pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)), \
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
#define SPLINE_RESOL_CAP_MAX
#define SPLINE_RESOL_CAP_MIN
BLI_INLINE uint clampis_uint(const uint v, const uint min, const uint max)
#define SPLINE_RESOL_CAP_PER_PIXEL

Referenced by BKE_maskrasterize_handle_init().

◆ FACE_ASSERT

#define FACE_ASSERT ( face,
vert_max )
Value:
{ \
uint *_t = face; \
BLI_assert(_t[0] < vert_max); \
BLI_assert(_t[1] < vert_max); \
BLI_assert(_t[2] < vert_max); \
BLI_assert(_t[3] < vert_max || _t[3] == TRI_VERT); \
} \
(void)0
#define TRI_VERT

Definition at line 96 of file mask_rasterize.cc.

Referenced by BKE_maskrasterize_handle_init().

◆ SF_EDGE_IS_BOUNDARY

#define SF_EDGE_IS_BOUNDARY   0xff

Definition at line 87 of file mask_rasterize.cc.

Referenced by BKE_maskrasterize_handle_init().

◆ SF_KEYINDEX_TEMP_ID

#define SF_KEYINDEX_TEMP_ID   uint(-1)

Definition at line 88 of file mask_rasterize.cc.

Referenced by BKE_maskrasterize_handle_init().

◆ SPLINE_RESOL_CAP_MAX

#define SPLINE_RESOL_CAP_MAX   64

Definition at line 82 of file mask_rasterize.cc.

◆ SPLINE_RESOL_CAP_MIN

#define SPLINE_RESOL_CAP_MIN   8

Definition at line 81 of file mask_rasterize.cc.

◆ SPLINE_RESOL_CAP_PER_PIXEL

#define SPLINE_RESOL_CAP_PER_PIXEL   2

Definition at line 80 of file mask_rasterize.cc.

◆ TRI_TERMINATOR_ID

#define TRI_TERMINATOR_ID   uint(-1)

Definition at line 90 of file mask_rasterize.cc.

Referenced by layer_bucket_depth_from_xy(), and layer_bucket_init().

◆ TRI_VERT

◆ USE_SCANFILL_EDGE_WORKAROUND

#define USE_SCANFILL_EDGE_WORKAROUND

Definition at line 78 of file mask_rasterize.cc.

Function Documentation

◆ BKE_maskrasterize_buffer()

void BKE_maskrasterize_buffer ( MaskRasterHandle * mr_handle,
const uint width,
const uint height,
float * buffer )

Rasterize a buffer from a single mask (threaded execution).

Definition at line 1488 of file mask_rasterize.cc.

References BLI_parallel_range_settings_defaults(), BLI_task_parallel_range(), float, maskrasterize_buffer_cb(), and MaskRasterizeBufferData::mr_handle.

Referenced by edit_uv_mask_texture(), mask_rasterize(), and seq_render_mask().

◆ BKE_maskrasterize_handle_free()

◆ BKE_maskrasterize_handle_init()

void BKE_maskrasterize_handle_init ( MaskRasterHandle * mr_handle,
Mask * mask,
const int width,
const int height,
const bool do_aspect_correct,
const bool do_mask_aa,
const bool do_feather )

Definition at line 563 of file mask_rasterize.cc.

References add_v2_v2v2(), MaskLayer::alpha, BKE_mask_spline_differentiate_with_resolution(), BKE_mask_spline_feather_collapse_inner_loops(), BKE_mask_spline_feather_differentiated_points_with_resolution(), BKE_mask_spline_feather_resolution(), BKE_mask_spline_resolution(), MaskLayer::blend, MaskLayer::blend_flag, BLI_assert, BLI_listbase_count(), BLI_memarena_free(), BLI_memarena_new(), BLI_movelisttolist(), BLI_rctf_do_minmax_v(), BLI_rctf_init_minmax(), BLI_rctf_isect(), BLI_rctf_union(), BLI_remlink(), BLI_SCANFILL_ARENA_SIZE, BLI_scanfill_begin_arena(), BLI_scanfill_calc_ex(), BLI_SCANFILL_CALC_HOLES, BLI_SCANFILL_CALC_POLYS, BLI_scanfill_calc_self_isect(), BLI_scanfill_edge_add(), BLI_scanfill_end_arena(), bounds(), MaskRasterHandle::bounds, ScanFillEdge::c, CALC_CAP_RESOL, ScanFillVert::co, copy_v3_v3(), cos(), FACE_ASSERT, MaskRasterLayer::face_tot, MaskLayer::falloff, ScanFillContext::filledgebase, ScanFillContext::fillfacebase, ScanFillContext::fillvertbase, ListBase::first, MaskLayer::flag, float, is_cyclic(), MaskRasterSplineInfo::is_cyclic, ScanFillVert::keyindex, ListBase::last, layer_bucket_init(), layer_bucket_init_dummy(), MaskRasterHandle::layers, MaskRasterHandle::layers_tot, LISTBASE_FOREACH, M_PI, MASK_HIDE_RENDER, MASK_LAYERFLAG_FILL_DISCRETE, MASK_LAYERFLAG_FILL_OVERLAP, MASK_SPLINE_CYCLIC, MASK_SPLINE_NOFILL, MASK_SPLINE_NOINTERSECT, maskrasterize_spline_differentiate_point_outset(), MEM_freeN(), MEM_mallocN, MEM_reallocN, min_ii(), MaskLayer::next, ScanFillFace::next, ScanFillVert::next, ScanFillContext::poly_nr, rotate_point_v2(), scanfill_vert_add_v2_with_depth(), SF_EDGE_IS_BOUNDARY, SF_KEYINDEX_TEMP_ID, MaskLayer::splines, sub_v2_v2v2(), ScanFillEdge::tmp, ScanFillVert::tmp, TRI_VERT, ScanFillVert::u, UNUSED_VARS_NDEBUG, ScanFillEdge::v1, ScanFillFace::v1, ScanFillEdge::v2, ScanFillFace::v2, ScanFillFace::v3, MaskRasterSplineInfo::vertex_offset, MaskRasterSplineInfo::vertex_total, MaskRasterSplineInfo::vertex_total_cap_head, MaskRasterSplineInfo::vertex_total_cap_tail, and MaskLayer::visibility_flag.

Referenced by edit_uv_mask_texture(), blender::realtime_compositor::get_mask_raster_handles(), blender::compositor::MaskOperation::init_execution(), mask_rasterize(), and seq_render_mask().

◆ BKE_maskrasterize_handle_new()

◆ BKE_maskrasterize_handle_sample()

◆ clampis_uint()

BLI_INLINE uint clampis_uint ( const uint v,
const uint min,
const uint max )

Definition at line 132 of file mask_rasterize.cc.

References max, min, and v.

◆ layer_bucket_depth_from_xy()

static float layer_bucket_depth_from_xy ( MaskRasterLayer * layer,
const float xy[2] )
static

◆ layer_bucket_index_from_xy()

BLI_INLINE uint layer_bucket_index_from_xy ( MaskRasterLayer * layer,
const float xy[2] )

Definition at line 1323 of file mask_rasterize.cc.

References BLI_assert, BLI_rctf_isect_pt_v(), and xy.

Referenced by layer_bucket_depth_from_xy().

◆ layer_bucket_init()

◆ layer_bucket_init_dummy()

static void layer_bucket_init_dummy ( MaskRasterLayer * layer)
static

Definition at line 384 of file mask_rasterize.cc.

References BLI_rctf_init().

Referenced by BKE_maskrasterize_handle_init().

◆ layer_bucket_isect_test()

static bool layer_bucket_isect_test ( const MaskRasterLayer * layer,
uint face_index,
const uint bucket_x,
const uint bucket_y,
const float bucket_size_x,
const float bucket_size_y,
const float bucket_max_rad_squared )
static

◆ maskrasterize_buffer_cb()

static void maskrasterize_buffer_cb ( void *__restrict userdata,
const int y,
const TaskParallelTLS * __restrict )
static

Definition at line 1465 of file mask_rasterize.cc.

References BKE_maskrasterize_handle_sample(), float, and xy.

Referenced by BKE_maskrasterize_buffer().

◆ maskrasterize_layer_isect()

static float maskrasterize_layer_isect ( const uint * face,
float(*) cos[3],
const float dist_orig,
const float xy[2] )
static

◆ maskrasterize_layer_z_depth_quad()

static float maskrasterize_layer_z_depth_quad ( const float pt[2],
const float v1[3],
const float v2[3],
const float v3[3],
const float v4[3] )
static

Definition at line 1253 of file mask_rasterize.cc.

References barycentric_weights_v2_quad(), v2, and w().

Referenced by maskrasterize_layer_isect().

◆ maskrasterize_spline_differentiate_point_outset()

static void maskrasterize_spline_differentiate_point_outset ( float(*) diff_feather_points[2],
float(*) diff_points[2],
const uint tot_diff_point,
const float ofs,
const bool do_test )
static

◆ rotate_point_v2()

static void rotate_point_v2 ( float r_p[2],
const float p[2],
const float cent[2],
const float angle,
const float asp[2] )
static

Definition at line 112 of file mask_rasterize.cc.

References cosf, and sinf.

Referenced by BKE_maskrasterize_handle_init().

◆ scanfill_vert_add_v2_with_depth()

static ScanFillVert * scanfill_vert_add_v2_with_depth ( ScanFillContext * sf_ctx,
const float co_xy[2],
const float co_z )
static

Definition at line 137 of file mask_rasterize.cc.

References BLI_scanfill_vert_add().

Referenced by BKE_maskrasterize_handle_init().

Variable Documentation

◆ LOG

CLG_LogRef LOG = {"bke.mask_rasterize"}
static

Definition at line 110 of file mask_rasterize.cc.

Referenced by BKE_maskrasterize_handle_sample().