[Bf-blender-cvs] [943aed0de35] master: ImBuf: Extracted UV Wrapping from the Interpolation functions.

Jeroen Bakker noreply at git.blender.org
Fri Dec 10 16:18:03 CET 2021


Commit: 943aed0de35621e32896bc14d67dd261d7ce6c01
Author: Jeroen Bakker
Date:   Fri Dec 10 16:14:36 2021 +0100
Branches: master
https://developer.blender.org/rB943aed0de35621e32896bc14d67dd261d7ce6c01

ImBuf: Extracted UV Wrapping from the Interpolation functions.

Improvement of the IMB_transform function by separating the UVWrapping
method from the color interpolation function. This would allow us to
perform uv wrapping operations separate from the interpolation function.

Currently this wrapping is only supported when interpolating colors.
This change would allow us to perform it on non-color image buffers.

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

M	source/blender/imbuf/intern/transform.cc

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

diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc
index 7c130c658c4..caa43fc4e8d 100644
--- a/source/blender/imbuf/intern/transform.cc
+++ b/source/blender/imbuf/intern/transform.cc
@@ -192,6 +192,68 @@ class TexelPointer {
   }
 };
 
+/**
+ * \brief Wrapping mode for the uv coordinates.
+ *
+ * Subclasses have the ability to change the UV coordinates before the source buffer will be
+ * sampled.
+ */
+class BaseUVWrapping {
+ public:
+  /**
+   * \brief modify the given u coordinate.
+   */
+  virtual float modify_u(const TransformUserData &user_data, float u) = 0;
+
+  /**
+   * \brief modify the given v coordinate.
+   */
+  virtual float modify_v(const TransformUserData &user_data, float v) = 0;
+};
+
+/**
+ * \brief UVWrapping method that does not modify the UV coordinates.
+ */
+class PassThroughUV : public BaseUVWrapping {
+ public:
+  float modify_u(const TransformUserData &UNUSED(user_data), float u) override
+  {
+    return u;
+  }
+
+  float modify_v(const TransformUserData &UNUSED(user_data), float v) override
+  {
+    return v;
+  }
+};
+
+/**
+ * \brief UVWrapping method that wrap repeats the UV coordinates.
+ */
+class WrapRepeatUV : public BaseUVWrapping {
+ public:
+  float modify_u(const TransformUserData &user_data, float u) override
+
+  {
+    int x = (int)floor(u);
+    x = x % user_data.src->x;
+    if (x < 0) {
+      x += user_data.src->x;
+    }
+    return x;
+  }
+
+  float modify_v(const TransformUserData &user_data, float v) override
+  {
+    int y = (int)floor(v);
+    y = y % user_data.src->y;
+    if (y < 0) {
+      y += user_data.src->y;
+    }
+    return y;
+  }
+};
+
 template<
     /**
      * \brief Discard function to use.
@@ -209,9 +271,16 @@ template<
      * \brief Kernel to store to the destination buffer.
      * Should be an TexelPointer
      */
-    typename OutputTexelPointer>
+    typename OutputTexelPointer,
+
+    /**
+     * \brief Wrapping method to perform
+     * Should be a subclass of BaseUVWrapper
+     */
+    typename UVWrapping>
 class ScanlineProcessor {
   Discard discarder;
+  UVWrapping uv_wrapping;
   OutputTexelPointer output;
 
  public:
@@ -225,8 +294,11 @@ class ScanlineProcessor {
     output.init_pixel_pointer(user_data->dst, 0, scanline);
     for (int xi = 0; xi < width; xi++) {
       if (!discarder.should_discard(*user_data, uv)) {
-        ColorInterpolation(
-            user_data->src, output.get_uchar_pointer(), output.get_float_pointer(), uv[0], uv[1]);
+        ColorInterpolation(user_data->src,
+                           output.get_uchar_pointer(),
+                           output.get_float_pointer(),
+                           uv_wrapping.modify_u(*user_data, uv[0]),
+                           uv_wrapping.modify_v(*user_data, uv[1]));
       }
 
       add_v2_v2(uv, user_data->add_x);
@@ -242,20 +314,26 @@ template<typename Processor> void transform_scanline_function(void *custom_data,
   processor.process(user_data, scanline);
 }
 
-template<InterpolationColorFunction DefaultFunction, InterpolationColorFunction WrapRepeatFunction>
+template<InterpolationColorFunction InterpolationFunction>
 ScanlineThreadFunc get_scanline_function(const eIMBTransformMode mode)
 
 {
   switch (mode) {
     case IMB_TRANSFORM_MODE_REGULAR:
-      return transform_scanline_function<
-          ScanlineProcessor<NoDiscard, DefaultFunction, TexelPointer<float, 4>>>;
+      return transform_scanline_function<ScanlineProcessor<NoDiscard,
+                                                           InterpolationFunction,
+                                                           TexelPointer<float, 4>,
+                                                           PassThroughUV>>;
     case IMB_TRANSFORM_MODE_CROP_SRC:
-      return transform_scanline_function<
-          ScanlineProcessor<CropSource, DefaultFunction, TexelPointer<float, 4>>>;
+      return transform_scanline_function<ScanlineProcessor<CropSource,
+                                                           InterpolationFunction,
+                                                           TexelPointer<float, 4>,
+                                                           PassThroughUV>>;
     case IMB_TRANSFORM_MODE_WRAP_REPEAT:
-      return transform_scanline_function<
-          ScanlineProcessor<NoDiscard, WrapRepeatFunction, TexelPointer<float, 4>>>;
+      return transform_scanline_function<ScanlineProcessor<NoDiscard,
+                                                           InterpolationFunction,
+                                                           TexelPointer<float, 4>,
+                                                           WrapRepeatUV>>;
   }
 
   BLI_assert_unreachable();
@@ -271,15 +349,13 @@ static void transform(TransformUserData *user_data, const eIMBTransformMode mode
     constexpr InterpolationColorFunction interpolation_function =
         Filter == IMB_FILTER_NEAREST ? nearest_interpolation_color_fl :
                                        bilinear_interpolation_color_fl;
-    scanline_func =
-        get_scanline_function<interpolation_function, nearest_interpolation_color_wrap>(mode);
+    scanline_func = get_scanline_function<interpolation_function>(mode);
   }
   else if (user_data->dst->rect) {
     constexpr InterpolationColorFunction interpolation_function =
         Filter == IMB_FILTER_NEAREST ? nearest_interpolation_color_char :
                                        bilinear_interpolation_color_char;
-    scanline_func =
-        get_scanline_function<interpolation_function, nearest_interpolation_color_wrap>(mode);
+    scanline_func = get_scanline_function<interpolation_function>(mode);
   }
 
   if (scanline_func != nullptr) {



More information about the Bf-blender-cvs mailing list