[Bf-blender-cvs] [55a56ec] compositor-2016: Implemented the hilbert spiral

Monique Dewanchand noreply at git.blender.org
Wed Jun 1 22:31:12 CEST 2016


Commit: 55a56ec058f0d1dc46b1e688034791a090ce4e44
Author: Monique Dewanchand
Date:   Wed Jun 1 22:11:58 2016 +0200
Branches: compositor-2016
https://developer.blender.org/rB55a56ec058f0d1dc46b1e688034791a090ce4e44

Implemented the hilbert spiral

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

M	source/blender/compositor/cmp/cmp_tilemanager.cpp
M	source/blender/compositor/kernel/cvm/cvm_node_blur.h
M	source/blender/compositor/kernel/kernel_functions.h

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

diff --git a/source/blender/compositor/cmp/cmp_tilemanager.cpp b/source/blender/compositor/cmp/cmp_tilemanager.cpp
index 79d90e2..fa2e837 100644
--- a/source/blender/compositor/cmp/cmp_tilemanager.cpp
+++ b/source/blender/compositor/cmp/cmp_tilemanager.cpp
@@ -30,7 +30,6 @@ namespace Compositor {
   	DIRECTION_RIGHT,
   };
 
-
   TileManager::TileManager(Output* output) {
     this->output = output;
   }
@@ -39,19 +38,89 @@ namespace Compositor {
     Node* node = output->node;
     const int width = output->width;
     const int height = output->height;
-    const int tile_size = output->node_tree->chunksize;
 
-    for (int x = 0 ; x <= width; x += tile_size) {
-      int x_max = x+tile_size;
-      if (x_max > width) x_max = width;
-      for (int y = 0;y <= height; y += tile_size) {
-        int y_max = y+tile_size;
-        if (y_max > height) y_max = height;
+    int2 tile_size = make_int2(output->node_tree->chunksize, output->node_tree->chunksize);
+    const int hilbert_size = (max(tile_size.x, tile_size.y) <= 12)? 8: 4;
+    int tile_w = (tile_size.x >= width)? 1: (width + tile_size.x - 1)/tile_size.x;
+    int tile_h = (tile_size.y >= height)? 1: (height + tile_size.y - 1)/tile_size.y;
+    int2 center = make_int2(width/2, height/2);
+    const int num = 1; // fixed number of devices.
+    int tile_per_device = (tile_w * tile_h + num -1) / num;
 
-        Compositor::Device::Task* task = new Compositor::Device::Task(node, x, y, x_max, y_max, this->output);
-        tiles.push_back(task);
-      }
-    }
+    int2 block_size = tile_size * make_int2(hilbert_size, hilbert_size);
+    /* Number of blocks to fill the image */
+		int blocks_x = (block_size.x >= width)? 1: (width + block_size.x - 1)/block_size.x;
+		int blocks_y = (block_size.y >= height)? 1: (height + block_size.y - 1)/block_size.y;
+		int n = max(blocks_x, blocks_y) | 0x1; /* Side length of the spiral (must be odd) */
+		/* Offset of spiral (to keep it centered) */
+    int2 offset = make_int2((width - n*block_size.x)/2, (height - n*block_size.y)/2);
+		offset = (offset / tile_size) * tile_size; /* Round to tile border. */
+
+    int2 block = make_int2(0, 0); /* Current block */
+    SpiralDirection prev_dir = DIRECTION_UP, dir = DIRECTION_UP;
+    for(int i = 0;;) {
+      /* Generate the tiles in the current block. */
+			for(int hilbert_index = 0; hilbert_index < hilbert_size*hilbert_size; hilbert_index++) {
+				int2 tile, hilbert_pos = hilbert_index_to_pos(hilbert_size, hilbert_index);
+				/* Rotate block according to spiral direction. */
+				if(prev_dir == DIRECTION_UP && dir == DIRECTION_UP) {
+					tile = make_int2(hilbert_pos.y, hilbert_pos.x);
+				}
+				else if(dir == DIRECTION_LEFT || prev_dir == DIRECTION_LEFT) {
+					tile = hilbert_pos;
+				}
+				else if(dir == DIRECTION_DOWN) {
+					tile = make_int2(hilbert_size-1-hilbert_pos.y, hilbert_size-1-hilbert_pos.x);
+				}
+				else {
+					tile = make_int2(hilbert_size-1-hilbert_pos.x, hilbert_size-1-hilbert_pos.y);
+				}
+
+				int2 pos = block*block_size + tile*tile_size + offset;
+				/* Only add tiles which are in the image (tiles outside of the image can be generated since the spiral is always square). */
+				if(pos.x >= 0 && pos.y >= 0 && pos.x < width && pos.y < height) {
+					int w = min(tile_size.x, width - pos.x);
+					int h = min(tile_size.y, height - pos.y);
+
+          Compositor::Device::Task* task = new Compositor::Device::Task(node, pos.x, pos.y, pos.x+w, pos.y+h, this->output);
+          tiles.push_front(task);
+				}
+			}
+
+			/* Stop as soon as the spiral has reached the center block. */
+			if(block.x == (n-1)/2 && block.y == (n-1)/2)
+				break;
+
+			/* Advance to next block. */
+			prev_dir = dir;
+			switch(dir) {
+				case DIRECTION_UP:
+					block.y++;
+					if(block.y == (n-i-1)) {
+						dir = DIRECTION_LEFT;
+					}
+					break;
+				case DIRECTION_LEFT:
+					block.x++;
+					if(block.x == (n-i-1)) {
+						dir = DIRECTION_DOWN;
+					}
+					break;
+				case DIRECTION_DOWN:
+					block.y--;
+					if(block.y == i) {
+						dir = DIRECTION_RIGHT;
+					}
+					break;
+				case DIRECTION_RIGHT:
+					block.x--;
+					if(block.x == i+1) {
+						dir = DIRECTION_UP;
+						i++;
+					}
+					break;
+			}
+		}
   }
   void TileManager::delete_tiles(std::list<Compositor::Device::Task*>& tiles) {
     while (!tiles.empty())
diff --git a/source/blender/compositor/kernel/cvm/cvm_node_blur.h b/source/blender/compositor/kernel/cvm/cvm_node_blur.h
index 0f0bd45..9480eaf 100644
--- a/source/blender/compositor/kernel/cvm/cvm_node_blur.h
+++ b/source/blender/compositor/kernel/cvm/cvm_node_blur.h
@@ -4,22 +4,22 @@ CVM_float4_node_start(blur)
   float blur_size = global.width * node.var_float_0;
   float blur_size_squared = blur_size * blur_size;
 
-  if (global.phase == KG_PHASE_REFINE) {
+  // if (global.phase == KG_PHASE_REFINE) {
     float2 move = (rand_float2(xy) * 2.f - 1.f) * blur_size;
     if (length_squared(move) <= blur_size_squared)
       return CVM_float4_node_call(0, xy+move, sample_weight);
 
     __cvm_out_set sample_weight = 0.;
     return make_float4(0.f, 0.f, 0.f, 0.f);
-  } else {
-    // TODO: FINAL do not randomize
-    float2 move = (rand_float2(xy) * 2.f - 1.f) * blur_size;
-    if (length_squared(move) <= blur_size_squared)
-      return CVM_float4_node_call(0, xy+move, sample_weight);
-
-    __cvm_out_set sample_weight = 1.;
-    return make_float4(1.f, 0.f, 0.f, 0.f);
-  }
+  // } else {
+  //   // TODO: FINAL do not randomize
+  //   float2 move = (rand_float2(xy) * 2.f - 1.f) * blur_size;
+  //   if (length_squared(move) <= blur_size_squared)
+  //     return CVM_float4_node_call(0, xy+move, sample_weight);
+  //
+  //   __cvm_out_set sample_weight = 1.;
+  //   return make_float4(1.f, 0.f, 0.f, 0.f);
+  // }
 
 
 CVM_float4_node_end
diff --git a/source/blender/compositor/kernel/kernel_functions.h b/source/blender/compositor/kernel/kernel_functions.h
index 5c96f18..d41f7a1 100644
--- a/source/blender/compositor/kernel/kernel_functions.h
+++ b/source/blender/compositor/kernel/kernel_functions.h
@@ -9,6 +9,7 @@ __cvm_inline float4 make_float4(float x, float y, float z, float w) { return (fl
 __cvm_inline int2 operator+(const int2 a, const int2 b) { return make_int2(a.x+b.x, a.y+b.y); }
 __cvm_inline int2 operator-(const int2 a, const int2 b) { return make_int2(a.x-b.x, a.y-b.y); }
 __cvm_inline int2 operator*(const int2 a, const int2 b) { return make_int2(a.x*b.x, a.y*b.y); }
+__cvm_inline int2 operator/(const int2 a, const int2 b) { return make_int2(a.x/b.x, a.y/b.y); }
 __cvm_inline int2 operator+=(int2& a, const int2& b) { return a = a + b; }
 
 
@@ -19,6 +20,8 @@ __cvm_inline float2 operator-(const float2 a, float f) { return make_float2(a.x-
 
 #include <algorithm>
 using std::swap;
+using std::max;
+using std::min;
 
 __cvm_inline float length_squared(float2 a) { return a.x*a.x + a.y*a.y; }
 __cvm_inline float length(float2 a) { return std::sqrt(length_squared(a)); }




More information about the Bf-blender-cvs mailing list