[Bf-blender-cvs] [8278ad3dfb3] master: Fix T90799: Box/Ellipse Mask node masking is off-centered

Manuel Castilla noreply at git.blender.org
Wed Oct 13 23:46:46 CEST 2021


Commit: 8278ad3dfb326359f4f8196dc375d952d43c93c7
Author: Manuel Castilla
Date:   Wed Oct 13 23:02:15 2021 +0200
Branches: master
https://developer.blender.org/rB8278ad3dfb326359f4f8196dc375d952d43c93c7

Fix T90799: Box/Ellipse Mask node masking is off-centered

This is especially noticeable when using the default center with full
width and height as some borders are masked by 1 pixel.

The relative coordinates are now calculated respect the last ones
instead of the dimensions for centering, and the limits
are inclusive to mask more accurately.

===================================================================

M	source/blender/compositor/operations/COM_BoxMaskOperation.cc
M	source/blender/compositor/operations/COM_EllipseMaskOperation.cc

===================================================================

diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc
index adfe7fcd87a..c79179a3e0a 100644
--- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc
@@ -48,8 +48,8 @@ void BoxMaskOperation::execute_pixel_sampled(float output[4],
   float input_mask[4];
   float input_value[4];
 
-  float rx = x / this->get_width();
-  float ry = y / this->get_height();
+  float rx = x / MAX2(this->get_width() - 1.0f, FLT_EPSILON);
+  float ry = y / MAX2(this->get_height() - 1.0f, FLT_EPSILON);
 
   const float dy = (ry - data_->y) / aspect_ratio_;
   const float dx = rx - data_->x;
@@ -59,10 +59,10 @@ void BoxMaskOperation::execute_pixel_sampled(float output[4],
   input_mask_->read_sampled(input_mask, x, y, sampler);
   input_value_->read_sampled(input_value, x, y, sampler);
 
-  float half_height = data_->height / 2.0f;
-  float half_width = data_->width / 2.0f;
-  bool inside = (rx > data_->x - half_width && rx < data_->x + half_width &&
-                 ry > data_->y - half_height && ry < data_->y + half_height);
+  float half_height = data_->height / 2.0f + FLT_EPSILON;
+  float half_width = data_->width / 2.0f + FLT_EPSILON;
+  bool inside = (rx >= data_->x - half_width && rx <= data_->x + half_width &&
+                 ry >= data_->y - half_height && ry <= data_->y + half_height);
 
   switch (mask_type_) {
     case CMP_NODE_MASKTYPE_ADD:
@@ -144,20 +144,20 @@ void BoxMaskOperation::apply_mask(MemoryBuffer *output,
                                   Span<MemoryBuffer *> inputs,
                                   MaskFunc mask_func)
 {
-  const float op_w = this->get_width();
-  const float op_h = this->get_height();
-  const float half_w = data_->width / 2.0f;
-  const float half_h = data_->height / 2.0f;
+  const float op_last_x = MAX2(this->get_width() - 1.0f, FLT_EPSILON);
+  const float op_last_y = MAX2(this->get_height() - 1.0f, FLT_EPSILON);
+  const float half_w = data_->width / 2.0f + FLT_EPSILON;
+  const float half_h = data_->height / 2.0f + FLT_EPSILON;
   for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
-    const float op_ry = it.y / op_h;
+    const float op_ry = it.y / op_last_y;
     const float dy = (op_ry - data_->y) / aspect_ratio_;
-    const float op_rx = it.x / op_w;
+    const float op_rx = it.x / op_last_x;
     const float dx = op_rx - data_->x;
     const float rx = data_->x + (cosine_ * dx + sine_ * dy);
     const float ry = data_->y + (-sine_ * dx + cosine_ * dy);
 
-    const bool inside = (rx > data_->x - half_w && rx < data_->x + half_w &&
-                         ry > data_->y - half_h && ry < data_->y + half_h);
+    const bool inside = (rx >= data_->x - half_w && rx <= data_->x + half_w &&
+                         ry >= data_->y - half_h && ry <= data_->y + half_h);
     const float *mask = it.in(0);
     const float *value = it.in(1);
     *it.out = mask_func(inside, mask, value);
diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
index 19497c38131..a051e06d15e 100644
--- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
@@ -48,8 +48,8 @@ void EllipseMaskOperation::execute_pixel_sampled(float output[4],
   float input_mask[4];
   float input_value[4];
 
-  float rx = x / this->get_width();
-  float ry = y / this->get_height();
+  float rx = x / MAX2(this->get_width() - 1.0f, FLT_EPSILON);
+  float ry = y / MAX2(this->get_height() - 1.0f, FLT_EPSILON);
 
   const float dy = (ry - data_->y) / aspect_ratio_;
   const float dx = rx - data_->x;
@@ -68,7 +68,7 @@ void EllipseMaskOperation::execute_pixel_sampled(float output[4],
   sy *= sy;
   const float ty = half_height * half_height;
 
-  bool inside = ((sx / tx) + (sy / ty)) < 1.0f;
+  bool inside = ((sx / tx) + (sy / ty)) <= (1.0f + FLT_EPSILON);
 
   switch (mask_type_) {
     case CMP_NODE_MASKTYPE_ADD:
@@ -152,20 +152,20 @@ void EllipseMaskOperation::apply_mask(MemoryBuffer *output,
 {
   const MemoryBuffer *input_mask = inputs[0];
   const MemoryBuffer *input_value = inputs[1];
-  const float op_w = this->get_width();
-  const float op_h = this->get_height();
+  const float op_last_x = MAX2(this->get_width() - 1.0f, FLT_EPSILON);
+  const float op_last_y = MAX2(this->get_height() - 1.0f, FLT_EPSILON);
   const float half_w = data_->width / 2.0f;
   const float half_h = data_->height / 2.0f;
   const float tx = half_w * half_w;
   const float ty = half_h * half_h;
   for (int y = area.ymin; y < area.ymax; y++) {
-    const float op_ry = y / op_h;
+    const float op_ry = y / op_last_y;
     const float dy = (op_ry - data_->y) / aspect_ratio_;
     float *out = output->get_elem(area.xmin, y);
     const float *mask = input_mask->get_elem(area.xmin, y);
     const float *value = input_value->get_elem(area.xmin, y);
     for (int x = area.xmin; x < area.xmax; x++) {
-      const float op_rx = x / op_w;
+      const float op_rx = x / op_last_x;
       const float dx = op_rx - data_->x;
       const float rx = data_->x + (cosine_ * dx + sine_ * dy);
       const float ry = data_->y + (-sine_ * dx + cosine_ * dy);
@@ -173,7 +173,7 @@ void EllipseMaskOperation::apply_mask(MemoryBuffer *output,
       sx *= sx;
       float sy = ry - data_->y;
       sy *= sy;
-      const bool inside = ((sx / tx) + (sy / ty)) < 1.0f;
+      const bool inside = ((sx / tx) + (sy / ty)) <= (1.0f + FLT_EPSILON);
       out[0] = mask_func(inside, mask, value);
 
       mask += input_mask->elem_stride;



More information about the Bf-blender-cvs mailing list