[#21660] improved UV test grid
authorCampbell Barton <ideasman42@gmail.com>
Sun, 21 Mar 2010 00:25:52 +0000 (00:25 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 21 Mar 2010 00:25:52 +0000 (00:25 +0000)
from shuvro sarker (shuvro)
Added text to the patch and made other minor tweaks.

moved image generation functions into their own file.

source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/image_gen.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_image.c

index d1808366944b543957e1195371e9959423ca9bb9..df51d0175943cb090f1758114477630fb67a132a 100644 (file)
@@ -162,6 +162,11 @@ struct Image *BKE_image_copy(struct Image *ima);
 /* merge source into dest, and free source */
 void BKE_image_merge(struct Image *dest, struct Image *source);
 
+/* image_gen.c */
+void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]);
+void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width);
+void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int height, int width);
+
 #ifdef __cplusplus
 }
 #endif
index f870fc1083bde0294fd6c80fda3e7777bbca25fc..25a4f9b0a48f968d8d59ef05877d2bf960eb1e37 100644 (file)
@@ -438,11 +438,8 @@ Image *BKE_add_image_file(const char *name, int frame)
 static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4])
 {
        ImBuf *ibuf;
-       float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
        unsigned char *rect= NULL;
        float *rect_float= NULL;
-       int x, y;
-       int checkerwidth=32, dark=1;
        
        if (floatbuf) {
                ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0);
@@ -456,107 +453,17 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, sho
        strcpy(ibuf->name, "//Untitled");
        ibuf->userflags |= IB_BITMAPDIRTY;
        
-       if (uvtestgrid) {
-               /* these two passes could be combined into one, but it's more readable and 
-               * easy to tweak like this, speed isn't really that much of an issue in this situation... */
-               
-               /* checkers */
-               for(y=0; y<height; y++) {
-                       dark = powf(-1.0f, floorf(y / checkerwidth));
-                       
-                       for(x=0; x<width; x++) {
-                               if (x % checkerwidth == 0) dark *= -1;
-                               
-                               if (floatbuf) {
-                                       if (dark > 0) {
-                                               rect_float[0] = rect_float[1] = rect_float[2] = 0.25f;
-                                               rect_float[3] = 1.0f;
-                                       } else {
-                                               rect_float[0] = rect_float[1] = rect_float[2] = 0.58f;
-                                               rect_float[3] = 1.0f;
-                                       }
-                                       rect_float+=4;
-                               }
-                               else {
-                                       if (dark > 0) {
-                                               rect[0] = rect[1] = rect[2] = 64;
-                                               rect[3] = 255;
-                                       } else {
-                                               rect[0] = rect[1] = rect[2] = 150;
-                                               rect[3] = 255;
-                                       }
-                                       rect += 4;
-                               }
-                       }
-               }
-               
-               /* 2nd pass, colored + */
-               if (floatbuf) rect_float= (float*)ibuf->rect_float;
-               else rect= (unsigned char*)ibuf->rect;
-               
-               for(y=0; y<height; y++) {
-                       hoffs = 0.125f * floorf(y / checkerwidth);
-                       
-                       for(x=0; x<width; x++) {
-                               h = 0.125f * floorf(x / checkerwidth);
-                               
-                               if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
-                                       (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
-                                       
-                                       if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
-                                               (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
-                                               
-                                               hue = fmodf(fabs(h-hoffs), 1.0f);
-                                               hsv_to_rgb(hue, s, v, &r, &g, &b);
-                                               
-                                               if (floatbuf) {
-                                                       rect_float[0]= r;
-                                                       rect_float[1]= g;
-                                                       rect_float[2]= b;
-                                                       rect_float[3]= 1.0f;
-                                               }
-                                               else {
-                                                       rect[0]= (char)(r * 255.0f);
-                                                       rect[1]= (char)(g * 255.0f);
-                                                       rect[2]= (char)(b * 255.0f);
-                                                       rect[3]= 255;
-                                               }
-                                       }
-                               }
+    switch(uvtestgrid) {
+    case 1:
+        BKE_image_buf_fill_checker(rect, rect_float, width, height);
+        break;
+    case 2:
+        BKE_image_buf_fill_checker_color(rect, rect_float, width, height);
+        break;
+    default:
+        BKE_image_buf_fill_color(rect, rect_float, width, height, color);
+    }
 
-                               if (floatbuf)
-                                       rect_float+=4;
-                               else
-                                       rect+=4;
-                       }
-               }
-       } else {        /* blank image */
-               char ccol[4];
-
-               ccol[0]= (char)(color[0]*255.0f);
-               ccol[1]= (char)(color[1]*255.0f);
-               ccol[2]= (char)(color[2]*255.0f);
-               ccol[3]= (char)(color[3]*255.0f);
-
-               for(y=0; y<height; y++) {
-                       for(x=0; x<width; x++) {
-                               if (floatbuf) {
-                                       rect_float[0]= color[0];
-                                       rect_float[1]= color[1];
-                                       rect_float[2]= color[2];
-                                       rect_float[3]= color[3];
-                                       rect_float+=4;
-                               }
-                               else {
-                                       rect[0]= ccol[0];
-                                       rect[1]= ccol[1];
-                                       rect[2]= ccol[2];
-                                       rect[3]= ccol[3];
-                                       rect+=4;
-                               }
-                       }
-               }
-       }
        return ibuf;
 }
 
@@ -1124,7 +1031,7 @@ extern int datatoc_bmonofont_ttf_size;
 extern char datatoc_bmonofont_ttf[];
 
 // XXX - copied from text_font_begin
-static void stamp_font_begin(int size)
+void stamp_font_begin(int size)
 {
        static int mono= -1;
 
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
new file mode 100644 (file)
index 0000000..e11ddfd
--- /dev/null
@@ -0,0 +1,360 @@
+/*  image_gen.c        
+ * 
+ * $Id: 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Matt Ebb, Campbell Barton, Shuvro Sarker
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include "BLI_math_color.h"
+#include "BLF_api.h"
+
+void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4])
+{
+       int x, y;
+
+       /* blank image */
+       if(rect_float) {
+               for(y= 0; y<height; y++) {
+                       for(x= 0; x<width; x++) {
+                               rect_float[0]= color[0];
+                               rect_float[1]= color[1];
+                               rect_float[2]= color[2];
+                               rect_float[3]= color[3];
+                               rect_float+= 4;
+                       }
+               }
+       }
+       
+       if(rect) {
+               char ccol[4];
+
+               ccol[0]= (char)(color[0]*255.0f);
+               ccol[1]= (char)(color[1]*255.0f);
+               ccol[2]= (char)(color[2]*255.0f);
+               ccol[3]= (char)(color[3]*255.0f);
+               for(y= 0; y<height; y++) {
+                       for(x= 0; x<width; x++) {
+                               
+                               rect[0]= ccol[0];
+                               rect[1]= ccol[1];
+                               rect[2]= ccol[2];
+                               rect[3]= ccol[3];
+                               rect+= 4;
+                       }
+               }
+       }
+}
+
+
+void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int width, int height)
+{
+       /* these two passes could be combined into one, but it's more readable and 
+       * easy to tweak like this, speed isn't really that much of an issue in this situation... */
+       int checkerwidth= 32, dark= 1;
+       int x, y;
+       
+       float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
+
+       /* checkers */
+       for(y= 0; y<height; y++) {
+               dark= powf(-1.0f, floorf(y / checkerwidth));
+               
+               for(x= 0; x<width; x++) {
+                       if (x % checkerwidth == 0) dark= -dark;
+                       
+                       if (rect_float) {
+                               if (dark > 0) {
+                                       rect_float[0]= rect_float[1]= rect_float[2]= 0.25f;
+                                       rect_float[3]= 1.0f;
+                               } else {
+                                       rect_float[0]= rect_float[1]= rect_float[2]= 0.58f;
+                                       rect_float[3]= 1.0f;
+                               }
+                               rect_float+= 4;
+                       }
+                       else {
+                               if (dark > 0) {
+                                       rect[0]= rect[1]= rect[2]= 64;
+                                       rect[3]= 255;
+                               } else {
+                                       rect[0]= rect[1]= rect[2]= 150;
+                                       rect[3]= 255;
+                               }
+                               rect+= 4;
+                       }
+               }
+       }
+       
+       /* 2nd pass, colored + */
+       for(y= 0; y<height; y++) {
+               hoffs= 0.125f * floorf(y / checkerwidth);
+               
+               for(x= 0; x<width; x++) {
+                       h= 0.125f * floorf(x / checkerwidth);
+                       
+                       if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
+                               (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
+                               
+                               if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
+                                       (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
+                                       
+                                       hue= fmodf(fabs(h-hoffs), 1.0f);
+                                       hsv_to_rgb(hue, s, v, &r, &g, &b);
+                                       
+                                       if (rect) {
+                                               rect[0]= (char)(r * 255.0f);
+                                               rect[1]= (char)(g * 255.0f);
+                                               rect[2]= (char)(b * 255.0f);
+                                               rect[3]= 255;
+                                       }
+                                       
+                                       if (rect_float) {
+                                               rect_float[0]= r;
+                                               rect_float[1]= g;
+                                               rect_float[2]= b;
+                                               rect_float[3]= 1.0f;
+                                       }
+                               }
+                       }
+
+                       if (rect_float) rect_float+= 4;
+                       if (rect) rect+= 4;
+               }
+       }
+}
+
+
+/* Utility functions for BKE_image_buf_fill_checker_color */
+
+#define BLEND_FLOAT(real, add)  (real+add <= 1.0) ? (real+add) : 1.0
+#define BLEND_CHAR(real, add) ((real + (char)(add * 255.0)) <= 255) ? (real + (char)(add * 255.0)) : 255
+
+static int is_pow2(int n)
+{
+       return ((n)&(n-1))==0;
+}
+static int larger_pow2(int n)
+{
+       if (is_pow2(n))
+               return n;
+
+       while(!is_pow2(n))
+               n= n&(n-1);
+
+       return n*2;
+}
+
+static void checker_board_color_fill(unsigned char *rect, float *rect_float, int width, int height)
+{
+       int hue_step, y, x;
+       float hue, val, sat, r, g, b;
+
+       sat= 1.0;
+
+       hue_step= larger_pow2(width / 8);
+    if(hue_step < 8) hue_step= 8;
+
+       for(y= 0; y < height; y++)
+       {
+        
+        val= 0.1 + (y * (0.4 / height)); /* use a number lower then 1.0 else its too bright */
+               for(x= 0; x < width; x++)
+               {
+                       hue= (float)((double)(x/hue_step) * 1.0 / width * hue_step);
+                       hsv_to_rgb(hue, sat, val, &r, &g, &b);
+
+                       if (rect) {
+                               rect[0]= (char)(r * 255.0f);
+                               rect[1]= (char)(g * 255.0f);
+                               rect[2]= (char)(b * 255.0f);
+                               rect[3]= 255;
+                               
+                               rect += 4;
+                       }
+
+                       if (rect_float) {
+                               rect_float[0]= r;
+                               rect_float[1]= g;
+                               rect_float[2]= b;
+                               rect_float[3]= 1.0f;
+                               
+                               rect_float += 4;
+                       }
+               }
+       }
+}
+
+static void checker_board_color_tint(unsigned char *rect, float *rect_float, int width, int height, int size, float blend)
+{
+       int x, y;
+       float blend_half= blend * 0.5f;
+
+       for(y= 0; y < height; y++)
+       {
+               for(x= 0; x < width; x++)
+               {
+                       if( ( (y/size)%2 == 1 && (x/size)%2 == 1 ) || ( (y/size)%2 == 0 && (x/size)%2 == 0 ) )
+                       {
+                               if (rect) {
+                                       rect[0]= (char)BLEND_CHAR(rect[0], blend);
+                                       rect[1]= (char)BLEND_CHAR(rect[1], blend);
+                                       rect[2]= (char)BLEND_CHAR(rect[2], blend);
+                                       rect[3]= 255;
+                               
+                                       rect += 4;
+                               }
+                               if (rect_float) {
+                                       rect_float[0]= BLEND_FLOAT(rect_float[0], blend);
+                                       rect_float[1]= BLEND_FLOAT(rect_float[1], blend);
+                                       rect_float[2]= BLEND_FLOAT(rect_float[2], blend);
+                                       rect_float[3]= 1.0f;
+                               
+                                       rect_float += 4;
+                               }
+                       }
+                       else {
+                               if (rect) {
+                                       rect[0]= (char)BLEND_CHAR(rect[0], blend_half);
+                                       rect[1]= (char)BLEND_CHAR(rect[1], blend_half);
+                                       rect[2]= (char)BLEND_CHAR(rect[2], blend_half);
+                                       rect[3]= 255;
+                               
+                                       rect += 4;
+                               }
+                               if (rect_float) {
+                                       rect_float[0]= BLEND_FLOAT(rect_float[0], blend_half);
+                                       rect_float[1]= BLEND_FLOAT(rect_float[1], blend_half);
+                                       rect_float[2]= BLEND_FLOAT(rect_float[2], blend_half);
+                                       rect_float[3]= 1.0f;
+                               
+                                       rect_float += 4;
+                               }
+                       }
+                       
+               }
+       }       
+}
+
+static void checker_board_grid_fill(unsigned char *rect, float *rect_float, int width, int height, float blend)
+{
+       int x, y;
+       for(y= 0; y < height; y++)
+       {
+               for(x= 0; x < width; x++)
+               {
+                       if( ((y % 32) == 0) || ((x % 32) == 0)  || x == 0 )
+                       {
+                               if (rect) {
+                                       rect[0]= BLEND_CHAR(rect[0], blend);
+                                       rect[1]= BLEND_CHAR(rect[1], blend);
+                                       rect[2]= BLEND_CHAR(rect[2], blend);
+                                       rect[3]= 255;
+
+                                       rect += 4;
+                               }
+                               if (rect_float) {
+                                       rect_float[0]= BLEND_FLOAT(rect_float[0], blend);
+                                       rect_float[1]= BLEND_FLOAT(rect_float[1], blend);
+                                       rect_float[2]= BLEND_FLOAT(rect_float[2], blend);
+                                       rect_float[3]= 1.0f;
+                               
+                                       rect_float += 4;
+                               }
+                       }
+                       else {
+                               if(rect_float) rect_float += 4;
+                               if(rect) rect += 4;
+                       }
+               }
+       }
+}
+
+/* defined in image.c */
+extern void stamp_font_begin(int size);
+
+static void checker_board_text(unsigned char *rect, float *rect_float, int width, int height, int step, int outline)
+{
+    int x, y;
+    int pen_x, pen_y;
+    char text[3]= {'A', '1', '\0'};
+
+    /* hard coded size! */
+       stamp_font_begin(54);
+    BLF_buffer(rect_float, rect, width, height, 4);
+    
+       for(y= 0; y < height; y+=step)
+       {
+        text[1]= '1';
+        
+               for(x= 0; x < width; x+=step)
+               {
+            /* hard coded offset */
+            pen_x = x + 33;
+            pen_y = y + 44;
+            
+            /* terribly crappy outline font! */
+            BLF_buffer_col(1.0, 1.0, 1.0, 1.0);
+
+            BLF_position(pen_x-outline, pen_y, 0.0);
+            BLF_draw_buffer(text);
+            BLF_position(pen_x+outline, pen_y, 0.0);
+            BLF_draw_buffer(text);
+            BLF_position(pen_x, pen_y-outline, 0.0);
+            BLF_draw_buffer(text);
+            BLF_position(pen_x, pen_y+outline, 0.0);
+            BLF_draw_buffer(text);
+            
+            BLF_position(pen_x-outline, pen_y-outline, 0.0);
+            BLF_draw_buffer(text);
+            BLF_position(pen_x+outline, pen_y+outline, 0.0);
+            BLF_draw_buffer(text);
+            BLF_position(pen_x-outline, pen_y+outline, 0.0);
+            BLF_draw_buffer(text);
+            BLF_position(pen_x+outline, pen_y-outline, 0.0);
+            BLF_draw_buffer(text);
+
+            BLF_buffer_col(0.0, 0.0, 0.0, 1.0);
+            BLF_position(pen_x, pen_y, 0.0);
+            BLF_draw_buffer(text);
+            
+            text[1]++;
+               }
+        text[0]++;
+       }
+    
+    /* cleanup the buffer. */
+       BLF_buffer(0, 0, 0, 0, 0);
+    
+}
+
+void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height)
+{
+       checker_board_color_fill(rect, rect_float, width, height);
+       checker_board_color_tint(rect, rect_float, width, height, 1, 0.03f);
+       checker_board_color_tint(rect, rect_float, width, height, 4, 0.05f);
+       checker_board_color_tint(rect, rect_float, width, height, 32, 0.07f);
+       checker_board_color_tint(rect, rect_float, width, height, 128, 0.15f);
+       checker_board_grid_fill(rect, rect_float, width, height, 1.0f/4.0f);
+
+       checker_board_text(rect, rect_float, width, height, 128, 2);
+}
index 1657ad00cdd1bad54e5eb1bc38b7123b7a783823..fdd79781d79d586d6c1ec495f6156039f180f259 100644 (file)
@@ -278,7 +278,8 @@ static void rna_def_image(BlenderRNA *brna)
                {0, NULL, 0, NULL, NULL}};
        static const EnumPropertyItem prop_generated_type_items[]= {
                {0, "BLANK", 0, "Blank", "Generate a blank image"},
-               {1, "UVGRID", 0, "UV Grid", "Generated grid to test UV mappings"},
+               {1, "UV_GRID", 0, "UV Grid", "Generated grid to test UV mappings"},
+               {2, "COLOR_GRID", 0, "Color Grid", "Generated improved UV grid to test UV mappings"},
                {0, NULL, 0, NULL, NULL}};
        static const EnumPropertyItem prop_mapping_items[]= {
                {0, "UV", 0, "UV Coordinates", "Use UV coordinates for mapping the image"},