// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::Voronoi(gaps::R2Grid*)
void R2Grid::
Voronoi(R2Grid *squared_distance_grid)
{
  int dist;
  int* old_dist;
  int* new_dist;
  RNScalar value;
  RNScalar *old_value;
  RNScalar *new_value;
  R2Grid *dgrid;
  int res,square,tmp_dist,first;
  int x,y,s,t,i;

  // Allocate distance grid
  if (squared_distance_grid) dgrid = squared_distance_grid;
  else dgrid = new R2Grid(XResolution(), YResolution());
  assert(dgrid);
  dgrid->SetWorldToGridTransformation(WorldToGridTransformation());

  // Allocate temporary buffers
  res = XResolution();
  if (res < YResolution()) res = YResolution();
  old_dist = new int[res];
  new_dist = new int[res];
  old_value = new RNScalar[res];
  new_value = new RNScalar[res];
  assert(old_dist && new_dist && old_value && new_value);

  // Initalize distance grid values (0 if was set, max_value if not)
  RNScalar max_value = 3 * (res+1) * (res+1);
  for (i = 0; i < grid_size; i++) {
    if (grid_values[i] == 0.0) dgrid->grid_values[i] = max_value;
    else dgrid->grid_values[i] = 0.0;
  }

  // Scan along x axis
  for (y = 0; y < YResolution(); y++) {
    first = 1;
    value = 0;
    dist = 0;
    for (x = 0; x < XResolution(); x++) {
      if (dgrid->GridValue(x,y) == 0.0) {
        first=0;
        dist=0;
        value = GridValue(x,y);
        assert(value != 0);
      }
      else if (first == 0) {
        dist++;
        square = dist*dist;
        dgrid->SetGridValue(x, y, square);
        SetGridValue(x, y, value);
        assert(value != 0);
      }
    }
			
    // backward scan
    dist = 0;
    first = 1;
    for (x = XResolution()-1; x >= 0; x--) {
      if (dgrid->GridValue(x,y) == 0.0){
        dist = 0;
        first = 0;
        value = GridValue(x,y);
        assert(value != 0);
      }
      else if (first == 0) {
        dist++;
        square = dist*dist;
        if (square < dgrid->GridValue(x, y)) {
          dgrid->SetGridValue(x, y, square);
          SetGridValue(x, y, value);
          assert(value != 0);
        }
      }
    }
  }

  // Scan along y axis
  for (x = 0; x < XResolution(); x++) {
    // Copy grid values
    for (y = 0; y < YResolution(); y++) {
      old_dist[y] = (int) (dgrid->GridValue(x, y));
      old_value[y] = GridValue(x, y);
    }
			
    // forward scan
    s = 0;
    for (y = 0; y < YResolution(); y++) {
      dist = old_dist[y];
      value = old_value[y];
      if (dist) {
        for (t = s; t <= y ; t++) {
          tmp_dist = old_dist[t] + (y - t) * (y - t);
          if (tmp_dist <= dist){
            dist = tmp_dist;
            value = old_value[t];
            s = t;
          }
        }
      }
      else { 
        s = y;
      }
      new_dist[y] = dist;
      new_value[y] = value;
    }

    // backward scan
    s = YResolution() - 1;
    for(y = YResolution()-1; y >=0 ; y--) {
      dist = new_dist[y];
      value = new_value[y];
      if (dist) {
        for (t = s; t > y ; t--) {
          tmp_dist = old_dist[t] + (y - t) * (y - t);
          if (tmp_dist <= dist){
            dist = tmp_dist;
            value = old_value[t];
            s = t;
          }
        }
        dgrid->SetGridValue(x, y, dist);
        SetGridValue(x, y, value);
      }
      else { 
        s = y; 
      }
    }
  }
	
  // Delete temporary buffers
  if (!squared_distance_grid) delete dgrid;
  delete[] old_dist;
  delete[] new_dist;
  delete[] old_value;
  delete[] new_value;
}

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x68(%rsp)
cmpq $0x0, 0xe8(%rsp)
je 0xaefe1
movq 0xe8(%rsp), %rax
movq %rax, 0xb0(%rsp)
jmp 0xaf058
movl $0xd0, %edi
callq 0xf4c0
movq 0x68(%rsp), %rdi
movq %rax, 0x58(%rsp)
callq 0xb9260
movl %eax, 0x64(%rsp)
jmp 0xaf000
movq 0x68(%rsp), %rdi
callq 0xb9280
movl %eax, 0x54(%rsp)
jmp 0xaf010
movl 0x54(%rsp), %edx
movl 0x64(%rsp), %esi
movq 0x58(%rsp), %rdi
callq 0xa61e0
jmp 0xaf024
movq 0x58(%rsp), %rax
movq %rax, 0xb0(%rsp)
jmp 0xaf058
movq 0x58(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x80(%rsp)
movl %eax, 0x7c(%rsp)
movl $0xd0, %esi
callq 0xf4d0
jmp 0xafa0a
movq 0x68(%rsp), %rdi
movq 0xb0(%rsp), %rax
movq %rax, 0x48(%rsp)
callq 0xb94e0
movq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0xa69b0
movq 0x68(%rsp), %rdi
callq 0xb9260
movq 0x68(%rsp), %rdi
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %eax
movl %eax, 0x50(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x50(%rsp), %eax
cmpl %ecx, %eax
jge 0xaf0bd
movq 0x68(%rsp), %rdi
callq 0xb9280
movl %eax, 0xac(%rsp)
movslq 0xac(%rsp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0xd8(%rsp)
movslq 0xac(%rsp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0xd0(%rsp)
movslq 0xac(%rsp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0xc0(%rsp)
movslq 0xac(%rsp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0xb8(%rsp)
movl 0xac(%rsp), %eax
addl $0x1, %eax
imull $0x3, %eax, %eax
movl 0xac(%rsp), %ecx
addl $0x1, %ecx
imull %ecx, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x70(%rsp)
movl $0x0, 0x8c(%rsp)
movq 0x68(%rsp), %rcx
movl 0x8c(%rsp), %eax
cmpl 0xcc(%rcx), %eax
jge 0xaf243
movq 0x68(%rsp), %rax
movq 0xb8(%rax), %rax
movslq 0x8c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xaf20c
jp 0xaf20c
movsd 0x70(%rsp), %xmm0
movq 0xb0(%rsp), %rax
movq 0xb8(%rax), %rax
movslq 0x8c(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0xaf22b
movq 0xb0(%rsp), %rax
movq 0xb8(%rax), %rax
movslq 0x8c(%rsp), %rcx
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0xaf22d
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0xaf1b0
movl $0x0, 0x98(%rsp)
movq 0x68(%rsp), %rdi
movl 0x98(%rsp), %eax
movl %eax, 0x44(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x44(%rsp), %eax
cmpl %ecx, %eax
jge 0xaf52e
movl $0x1, 0xa0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xc8(%rsp)
movl $0x0, 0xe4(%rsp)
movl $0x0, 0x9c(%rsp)
movq 0x68(%rsp), %rdi
movl 0x9c(%rsp), %eax
movl %eax, 0x40(%rsp)
callq 0xb9260
movl %eax, %ecx
movl 0x40(%rsp), %eax
cmpl %ecx, %eax
jge 0xaf3b0
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xaf320
jp 0xaf320
movq 0x68(%rsp), %rdi
movl $0x0, 0xa0(%rsp)
movl $0x0, 0xe4(%rsp)
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0xc8(%rsp)
jmp 0xaf398
cmpl $0x0, 0xa0(%rsp)
jne 0xaf396
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
movl 0xe4(%rsp), %eax
imull 0xe4(%rsp), %eax
movl %eax, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
cvtsi2sdl 0xa8(%rsp), %xmm0
callq 0x6bc00
movq 0x68(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
movsd 0xc8(%rsp), %xmm0
callq 0x6bc00
jmp 0xaf398
jmp 0xaf39a
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xaf29e
movq 0x68(%rsp), %rdi
movl $0x0, 0xe4(%rsp)
movl $0x1, 0xa0(%rsp)
callq 0xb9260
subl $0x1, %eax
movl %eax, 0x9c(%rsp)
cmpl $0x0, 0x9c(%rsp)
jl 0xaf516
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xaf44a
jp 0xaf44a
movq 0x68(%rsp), %rdi
movl $0x0, 0xe4(%rsp)
movl $0x0, 0xa0(%rsp)
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0xc8(%rsp)
jmp 0xaf4fe
cmpl $0x0, 0xa0(%rsp)
jne 0xaf4fc
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
movl 0xe4(%rsp), %eax
imull 0xe4(%rsp), %eax
movl %eax, 0xa8(%rsp)
cvtsi2sdl 0xa8(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
movsd 0x38(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0xaf4fa
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
cvtsi2sdl 0xa8(%rsp), %xmm0
callq 0x6bc00
movq 0x68(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
movsd 0xc8(%rsp), %xmm0
callq 0x6bc00
jmp 0xaf4fc
jmp 0xaf4fe
jmp 0xaf500
movl 0x9c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xaf3da
jmp 0xaf518
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0xaf24e
movl $0x0, 0x9c(%rsp)
movq 0x68(%rsp), %rdi
movl 0x9c(%rsp), %eax
movl %eax, 0x34(%rsp)
callq 0xb9260
movl %eax, %ecx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0xaf957
movl $0x0, 0x98(%rsp)
movq 0x68(%rsp), %rdi
movl 0x98(%rsp), %eax
movl %eax, 0x30(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x30(%rsp), %eax
cmpl %ecx, %eax
jge 0xaf5fb
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
movq 0x68(%rsp), %rdi
cvttsd2si %xmm0, %edx
movq 0xd8(%rsp), %rax
movslq 0x98(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
callq 0xb92a0
movq 0xc0(%rsp), %rax
movslq 0x98(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0xaf567
movl $0x0, 0x94(%rsp)
movl $0x0, 0x98(%rsp)
movq 0x68(%rsp), %rdi
movl 0x98(%rsp), %eax
movl %eax, 0x2c(%rsp)
callq 0xb9280
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0xaf797
movq 0xd8(%rsp), %rax
movslq 0x98(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0xe4(%rsp)
movq 0xc0(%rsp), %rax
movslq 0x98(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0xc8(%rsp)
cmpl $0x0, 0xe4(%rsp)
je 0xaf73b
movl 0x94(%rsp), %eax
movl %eax, 0x90(%rsp)
movl 0x90(%rsp), %eax
cmpl 0x98(%rsp), %eax
jg 0xaf739
movq 0xd8(%rsp), %rax
movslq 0x90(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl 0x98(%rsp), %ecx
subl 0x90(%rsp), %ecx
movl 0x98(%rsp), %edx
subl 0x90(%rsp), %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jg 0xaf721
movl 0xa4(%rsp), %eax
movl %eax, 0xe4(%rsp)
movq 0xc0(%rsp), %rax
movslq 0x90(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0xc8(%rsp)
movl 0x90(%rsp), %eax
movl %eax, 0x94(%rsp)
jmp 0xaf723
movl 0x90(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x90(%rsp)
jmp 0xaf688
jmp 0xaf749
movl 0x98(%rsp), %eax
movl %eax, 0x94(%rsp)
movl 0xe4(%rsp), %edx
movq 0xd0(%rsp), %rax
movslq 0x98(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movsd 0xc8(%rsp), %xmm0
movq 0xb8(%rsp), %rax
movslq 0x98(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0xaf611
movq 0x68(%rsp), %rdi
callq 0xb9280
movq 0x68(%rsp), %rdi
subl $0x1, %eax
movl %eax, 0x94(%rsp)
callq 0xb9280
subl $0x1, %eax
movl %eax, 0x98(%rsp)
cmpl $0x0, 0x98(%rsp)
jl 0xaf93f
movq 0xd0(%rsp), %rax
movslq 0x98(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0xe4(%rsp)
movq 0xb8(%rsp), %rax
movslq 0x98(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0xc8(%rsp)
cmpl $0x0, 0xe4(%rsp)
je 0xaf919
movl 0x94(%rsp), %eax
movl %eax, 0x90(%rsp)
movl 0x90(%rsp), %eax
cmpl 0x98(%rsp), %eax
jle 0xaf8d2
movq 0xd8(%rsp), %rax
movslq 0x90(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl 0x98(%rsp), %ecx
subl 0x90(%rsp), %ecx
movl 0x98(%rsp), %edx
subl 0x90(%rsp), %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
cmpl 0xe4(%rsp), %eax
jg 0xaf8ba
movl 0xa4(%rsp), %eax
movl %eax, 0xe4(%rsp)
movq 0xc0(%rsp), %rax
movslq 0x90(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0xc8(%rsp)
movl 0x90(%rsp), %eax
movl %eax, 0x94(%rsp)
jmp 0xaf8bc
movl 0x90(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x90(%rsp)
jmp 0xaf821
movq 0xb0(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
cvtsi2sdl 0xe4(%rsp), %xmm0
callq 0x6bc00
movq 0x68(%rsp), %rdi
movl 0x9c(%rsp), %esi
movl 0x98(%rsp), %edx
movsd 0xc8(%rsp), %xmm0
callq 0x6bc00
jmp 0xaf927
movl 0x98(%rsp), %eax
movl %eax, 0x94(%rsp)
jmp 0xaf929
movl 0x98(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0xaf7bf
jmp 0xaf941
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xaf539
cmpq $0x0, 0xe8(%rsp)
jne 0xaf990
movq 0xb0(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0xaf98e
movq 0x20(%rsp), %rdi
callq 0xa7690
movq 0x20(%rsp), %rdi
movl $0xd0, %esi
callq 0xf4d0
jmp 0xaf990
movq 0xd8(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0xaf9ad
movq 0x18(%rsp), %rdi
callq 0xf670
movq 0xd0(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0xaf9ca
movq 0x10(%rsp), %rdi
callq 0xf670
movq 0xc0(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0xaf9e7
movq 0x8(%rsp), %rdi
callq 0xf670
movq 0xb8(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0xafa02
movq (%rsp), %rdi
callq 0xf670
addq $0xf8, %rsp
retq
movq 0x80(%rsp), %rdi
callq 0xf890
nopw (%rax,%rax)