svn merge ^/trunk/blender -r48961:48967
This commit is contained in:
@@ -254,7 +254,7 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay)
|
||||
/* cyclic shapes are more usually used */
|
||||
// spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently
|
||||
|
||||
spline->weight_interp = MASK_SPLINE_INTERP_LINEAR;
|
||||
spline->weight_interp = MASK_SPLINE_INTERP_EASE;
|
||||
|
||||
BKE_mask_parent_init(&spline->parent);
|
||||
|
||||
|
||||
@@ -302,6 +302,10 @@ static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_ind
|
||||
|
||||
static void layer_bucket_init_dummy(MaskRasterLayer *layer)
|
||||
{
|
||||
layer->face_tot = 0;
|
||||
layer->face_coords = NULL;
|
||||
layer->face_array = NULL;
|
||||
|
||||
layer->buckets_x = 0;
|
||||
layer->buckets_y = 0;
|
||||
|
||||
@@ -309,6 +313,8 @@ static void layer_bucket_init_dummy(MaskRasterLayer *layer)
|
||||
layer->buckets_xy_scalar[1] = 0.0f;
|
||||
|
||||
layer->buckets_face = NULL;
|
||||
|
||||
BLI_rctf_init(&layer->bounds, -1.0f, -1.0f, -1.0f, -1.0f);
|
||||
}
|
||||
|
||||
static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
|
||||
@@ -383,14 +389,21 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
|
||||
CLAMP(ymax, 0.0f, 1.0f);
|
||||
|
||||
{
|
||||
const unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
|
||||
const unsigned int xi_max = (unsigned int) ((xmax - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
|
||||
const unsigned int yi_min = (unsigned int) ((ymin - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
|
||||
const unsigned int yi_max = (unsigned int) ((ymax - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
|
||||
unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
|
||||
unsigned int xi_max = (unsigned int) ((xmax - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
|
||||
unsigned int yi_min = (unsigned int) ((ymin - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
|
||||
unsigned int yi_max = (unsigned int) ((ymax - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
|
||||
void *face_index_void = SET_UINT_IN_POINTER(face_index);
|
||||
|
||||
unsigned int xi, yi;
|
||||
|
||||
/* this should _almost_ never happen but since it can in extreme cases,
|
||||
* we have to clamp the values or we overrun the buffer and crash */
|
||||
CLAMP(xi_min, 0, layer->buckets_x - 1);
|
||||
CLAMP(xi_max, 0, layer->buckets_x - 1);
|
||||
CLAMP(yi_min, 0, layer->buckets_y - 1);
|
||||
CLAMP(yi_max, 0, layer->buckets_y - 1);
|
||||
|
||||
for (yi = yi_min; yi <= yi_max; yi++) {
|
||||
unsigned int bucket_index = (layer->buckets_x * yi) + xi_min;
|
||||
for (xi = xi_min; xi <= xi_max; xi++, bucket_index++) {
|
||||
@@ -471,9 +484,9 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
|
||||
|
||||
for (masklay = mask->masklayers.first, masklay_index = 0; masklay; masklay = masklay->next, masklay_index++) {
|
||||
|
||||
const unsigned int tot_splines = BLI_countlist(&masklay->splines);
|
||||
/* we need to store vertex ranges for open splines for filling */
|
||||
MaskRasterSplineInfo *open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__);
|
||||
unsigned int tot_splines;
|
||||
MaskRasterSplineInfo *open_spline_ranges;
|
||||
unsigned int open_spline_index = 0;
|
||||
|
||||
MaskSpline *spline;
|
||||
@@ -487,10 +500,16 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
|
||||
unsigned int sf_vert_tot = 0;
|
||||
unsigned int tot_feather_quads = 0;
|
||||
|
||||
if (masklay->restrictflag & MASK_RESTRICT_RENDER) {
|
||||
if (masklay->restrictflag & MASK_RESTRICT_RENDER || masklay->alpha == 0.0f) {
|
||||
MaskRasterLayer *layer = &mr_handle->layers[masklay_index];
|
||||
layer_bucket_init_dummy(layer);
|
||||
layer->alpha = 0.0f; /* signal to skip this layer */
|
||||
continue;
|
||||
}
|
||||
|
||||
tot_splines = BLI_countlist(&masklay->splines);
|
||||
open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__);
|
||||
|
||||
BLI_scanfill_begin(&sf_ctx);
|
||||
|
||||
for (spline = masklay->splines.first; spline; spline = spline->next) {
|
||||
@@ -819,13 +838,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
|
||||
MEM_freeN(face_coords);
|
||||
MEM_freeN(face_array);
|
||||
|
||||
layer->face_tot = 0;
|
||||
layer->face_coords = NULL;
|
||||
layer->face_array = NULL;
|
||||
|
||||
layer_bucket_init_dummy(layer);
|
||||
|
||||
BLI_rctf_init(&layer->bounds, -1.0f, -1.0f, -1.0f, -1.0f);
|
||||
}
|
||||
|
||||
/* copy as-is */
|
||||
@@ -849,6 +862,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* 2D ray test */
|
||||
#if 0
|
||||
static float maskrasterize_layer_z_depth_tri(const float pt[2],
|
||||
const float v1[3], const float v2[3], const float v3[3])
|
||||
{
|
||||
@@ -856,14 +870,16 @@ static float maskrasterize_layer_z_depth_tri(const float pt[2],
|
||||
barycentric_weights_v2(v1, v2, v3, pt, w);
|
||||
return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
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])
|
||||
{
|
||||
float w[4];
|
||||
barycentric_weights_v2_quad(v1, v2, v3, v4, pt, w);
|
||||
return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]) + (v4[2] * w[3]);
|
||||
//return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]) + (v4[2] * w[3]);
|
||||
return w[2] + w[3]; /* we can make this assumption for small speedup */
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -904,8 +920,12 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons
|
||||
{
|
||||
|
||||
/* needs work */
|
||||
#if 0
|
||||
if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]])) {
|
||||
#if 1
|
||||
/* quad check fails for bowtie, so keep using 2 tri checks */
|
||||
//if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]))
|
||||
if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]]) ||
|
||||
isect_point_tri_v2(xy, cos[face[0]], cos[face[2]], cos[face[3]]))
|
||||
{
|
||||
return maskrasterize_layer_z_depth_quad(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]);
|
||||
}
|
||||
#elif 1
|
||||
@@ -978,6 +998,11 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
|
||||
for (i = 0; i < layers_tot; i++, layer++) {
|
||||
float value_layer;
|
||||
|
||||
/* also used as signal for unused layer (when render is disabled) */
|
||||
if (layer->alpha == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BLI_in_rctf_v(&layer->bounds, xy)) {
|
||||
value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy);
|
||||
|
||||
|
||||
@@ -1977,34 +1977,44 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3
|
||||
}
|
||||
|
||||
/* same as #barycentric_weights_v2 but works with a quad,
|
||||
* note: untested for values outside the quad's bounds.
|
||||
* note: there may be a more efficient method to do this, just figured it out - campbell */
|
||||
* note: untested for values outside the quad's bounds
|
||||
* this is #interp_weights_poly_v2 expanded for quads only */
|
||||
void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2],
|
||||
const float co[2], float w[4])
|
||||
{
|
||||
float wtot;
|
||||
#define MEAN_VALUE_HALF_TAN_V2(_area, i1, i2) ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \
|
||||
(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f)
|
||||
|
||||
const float areas_co[4] = {
|
||||
area_tri_signed_v2(v1, v2, co),
|
||||
area_tri_signed_v2(v2, v3, co),
|
||||
area_tri_signed_v2(v3, v4, co),
|
||||
area_tri_signed_v2(v4, v1, co),
|
||||
float wtot, area;
|
||||
|
||||
const float dirs[4][2] = {
|
||||
{v1[0] - co[0], v1[1] - co[1]},
|
||||
{v2[0] - co[0], v2[1] - co[1]},
|
||||
{v3[0] - co[0], v3[1] - co[1]},
|
||||
{v4[0] - co[0], v4[1] - co[1]},
|
||||
};
|
||||
|
||||
const float areas_diag[4] = {
|
||||
area_tri_signed_v2(v4, v1, v2),
|
||||
area_tri_signed_v2(v1, v2, v3),
|
||||
area_tri_signed_v2(v2, v3, v4),
|
||||
area_tri_signed_v2(v3, v4, v1),
|
||||
const float lens[4] = {
|
||||
len_v2(dirs[0]),
|
||||
len_v2(dirs[1]),
|
||||
len_v2(dirs[2]),
|
||||
len_v2(dirs[3]),
|
||||
};
|
||||
|
||||
const float u = areas_co[3] / (areas_co[1] + areas_co[3]);
|
||||
const float v = areas_co[0] / (areas_co[0] + areas_co[2]);
|
||||
/* inline mean_value_half_tan four times here */
|
||||
float t[4] = {
|
||||
MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
|
||||
MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
|
||||
MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
|
||||
MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
|
||||
};
|
||||
|
||||
w[0] = ((1.0f - u) * (1.0f - v)) * sqrtf(areas_diag[0] / areas_diag[2]);
|
||||
w[1] = (( u) * (1.0f - v)) * sqrtf(areas_diag[1] / areas_diag[3]);
|
||||
w[2] = (( u) * ( v)) * sqrtf(areas_diag[2] / areas_diag[0]);
|
||||
w[3] = ((1.0f - u) * ( v)) * sqrtf(areas_diag[3] / areas_diag[1]);
|
||||
#undef MEAN_VALUE_HALF_TAN_V2
|
||||
|
||||
w[0] = (t[3] + t[0]) / lens[0];
|
||||
w[1] = (t[0] + t[1]) / lens[1];
|
||||
w[2] = (t[1] + t[2]) / lens[2];
|
||||
w[3] = (t[2] + t[3]) / lens[3];
|
||||
|
||||
wtot = w[0] + w[1] + w[2] + w[3];
|
||||
|
||||
@@ -2190,6 +2200,7 @@ static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const
|
||||
|
||||
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
|
||||
{
|
||||
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
|
||||
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
|
||||
int i;
|
||||
|
||||
@@ -2217,6 +2228,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
|
||||
|
||||
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
|
||||
{
|
||||
/* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
|
||||
float totweight, t1, t2, len, *vmid, *vprev, *vnext;
|
||||
int i;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user