// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Grid.cpp
// Function: gaps::R3Grid::SquaredDistanceTransform()
void R3Grid::
SquaredDistanceTransform(void)
{
  int x,y,z,s,t;
  long long dist,square,new_dist;
  long long* oldBuffer;
  long long* newBuffer;
  int first;
  int i;

  // Allocate temporary buffers
  int res = XResolution();
  if (res < YResolution()) res = YResolution();
  if (res < ZResolution()) res = ZResolution();
  oldBuffer = new long long [res];
  assert(oldBuffer);
  newBuffer = new long long[res];
  assert(newBuffer);

  // Initalize values (0 if was set, max_value if not)
  RNScalar max_value = 3.0 * (res+1) * (res+1);
  RNScalar *grid_valuesp = grid_values;
  for (i = 0; i < grid_size; i++) {
    if (*grid_valuesp == 0.0) *grid_valuesp = max_value;
    else *grid_valuesp = 0.0;
    grid_valuesp++;
  }

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

  // Scan along x axis
  for (z = 0; z < ZResolution(); z++) {
    for (y = 0; y < YResolution(); y++) {
      // Copy grid values
      for(x = 0; x < XResolution(); x++) 
        oldBuffer[x] = (int) (GridValue(x, y, z) + 0.5);
		
      // forward scan
      s = 0;
      for (x = 0; x < XResolution(); x++) {
        dist = oldBuffer[x];
        if (dist) {
          for(t = s; t <= x; t++) {
            new_dist = oldBuffer[t] + (x - t) * (x - t);
            if (new_dist <= dist) {
              dist = new_dist;
              s = t;
            }
          }
        }
        else {
          s = x;
        }
        newBuffer[x] = dist;
      }
			
      // backwards scan
      s = XResolution() - 1;
      for (x = XResolution()-1; x >= 0 ; x--) {
        dist = newBuffer[x];
        if (dist) {
          for (t = s; t >= x; t--) {
            new_dist = oldBuffer[t] + (x - t) * (x - t);
            if (new_dist <= dist) {
              dist = new_dist;
              s = t;
            }
          }
          SetGridValue(x, y, z, dist);
        }
        else {
          s=x;
        }
      }
    }
  }
		
  // along y axis
  for (z = 0; z < ZResolution(); z++) {
    for (x = 0; x < XResolution(); x++) {
      // Copy grid values
      for (y = 0; y < YResolution(); y++)
        oldBuffer[y] = (int) (GridValue(x, y, z) + 0.5);
			
      // forward scan
      s = 0;
      for (y = 0; y < YResolution(); y++) {
        dist = oldBuffer[y];
        if (dist) {
          for (t = s; t <= y ; t++) {
            new_dist = oldBuffer[t] + (y - t) * (y - t);
            if (new_dist <= dist){
              dist = new_dist;
              s = t;
            }
          }
        }
        else { 
          s = y;
        }
        newBuffer[y] = dist;
      }

      // backward scan
      s = YResolution() - 1;
      for(y = YResolution()-1; y >=0 ; y--) {
        dist = newBuffer[y];
        if (dist) {
          for (t = s; t > y ; t--) {
            new_dist = oldBuffer[t] + (y - t) * (y - t);
            if (new_dist <= dist){
              dist = new_dist;
              s = t;
            }
          }
          SetGridValue(x, y, z, dist);
        }
        else { 
          s = y; 
        }
      }
    }
  }
	
  // Delete temporary buffers
  delete[] oldBuffer;
  delete[] newBuffer;
}

// Assembly:
subq $0xc8, %rsp
movq %rdi, 0xc0(%rsp)
movq 0xc0(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x138c0
movq 0x50(%rsp), %rdi
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
movl %eax, 0x5c(%rsp)
callq 0x138e0
movl %eax, %ecx
movl 0x5c(%rsp), %eax
cmpl %ecx, %eax
jge 0x58d6f
movq 0x50(%rsp), %rdi
callq 0x138e0
movl %eax, 0x74(%rsp)
movq 0x50(%rsp), %rdi
movl 0x74(%rsp), %eax
movl %eax, 0x4c(%rsp)
callq 0x13900
movl %eax, %ecx
movl 0x4c(%rsp), %eax
cmpl %ecx, %eax
jge 0x58d99
movq 0x50(%rsp), %rdi
callq 0x13900
movl %eax, 0x74(%rsp)
movslq 0x74(%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, 0x88(%rsp)
movslq 0x74(%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, %rcx
movq 0x50(%rsp), %rax
movq %rcx, 0x80(%rsp)
movl 0x74(%rsp), %ecx
addl $0x1, %ecx
cvtsi2sd %ecx, %xmm1
movsd 0xda3d0(%rip), %xmm0    # 0x1331e0
mulsd %xmm1, %xmm0
movl 0x74(%rsp), %ecx
addl $0x1, %ecx
cvtsi2sd %ecx, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x68(%rsp)
movq 0x230(%rax), %rax
movq %rax, 0x60(%rsp)
movl $0x0, 0x78(%rsp)
movq 0x50(%rsp), %rcx
movl 0x78(%rsp), %eax
cmpl 0x24c(%rcx), %eax
jge 0x58e9a
movq 0x60(%rsp), %rax
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x58e73
jp 0x58e73
movsd 0x68(%rsp), %xmm0
movq 0x60(%rsp), %rax
movsd %xmm0, (%rax)
jmp 0x58e7f
movq 0x60(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq 0x60(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x60(%rsp)
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0x58e3d
movl $0x0, 0xbc(%rsp)
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %eax
movl %eax, 0x48(%rsp)
callq 0x138c0
movl %eax, %ecx
movl 0x48(%rsp), %eax
cmpl %ecx, %eax
jge 0x59194
movl $0x0, 0xb8(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb8(%rsp), %eax
movl %eax, 0x44(%rsp)
callq 0x138e0
movl %eax, %ecx
movl 0x44(%rsp), %eax
cmpl %ecx, %eax
jge 0x5917c
movl $0x1, 0x7c(%rsp)
movq $0x0, 0xa0(%rsp)
movl $0x0, 0xb4(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb4(%rsp), %eax
movl %eax, 0x40(%rsp)
callq 0x13900
movl %eax, %ecx
movl 0x40(%rsp), %eax
cmpl %ecx, %eax
jge 0x59011
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
callq 0x6bad0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x58f9a
jp 0x58f9a
movq 0x50(%rsp), %rdi
movq $0x0, 0xa0(%rsp)
movl $0x0, 0x7c(%rsp)
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
xorps %xmm0, %xmm0
callq 0x6bc60
jmp 0x58ff9
cmpl $0x0, 0x7c(%rsp)
jne 0x58ff7
movq 0x50(%rsp), %rdi
movq 0xa0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
imulq 0xa0(%rsp), %rax
movq %rax, 0x98(%rsp)
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
cvtsi2sdq 0x98(%rsp), %xmm0
callq 0x6bc60
jmp 0x58ff9
jmp 0x58ffb
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x58f15
movq 0x50(%rsp), %rdi
movq $0x0, 0xa0(%rsp)
movl $0x1, 0x7c(%rsp)
callq 0x13900
subl $0x1, %eax
movl %eax, 0xb4(%rsp)
cmpl $0x0, 0xb4(%rsp)
jl 0x59164
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
callq 0x6bad0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x590ac
jp 0x590ac
movq 0x50(%rsp), %rdi
movq $0x0, 0xa0(%rsp)
movl $0x0, 0x7c(%rsp)
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
xorps %xmm0, %xmm0
callq 0x6bc60
jmp 0x5914c
cmpl $0x0, 0x7c(%rsp)
jne 0x5914a
movq 0x50(%rsp), %rdi
movq 0xa0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
imulq 0xa0(%rsp), %rax
movq %rax, 0x98(%rsp)
cvtsi2sdq 0x98(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
callq 0x6bad0
movsd 0x38(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x59148
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
cvtsi2sdq 0x98(%rsp), %xmm0
callq 0x6bc60
jmp 0x5914a
jmp 0x5914c
jmp 0x5914e
movl 0xb4(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x59039
jmp 0x59166
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x58ed3
jmp 0x5917e
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x58ea5
movl $0x0, 0xb4(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb4(%rsp), %eax
movl %eax, 0x34(%rsp)
callq 0x13900
movl %eax, %ecx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0x59551
movl $0x0, 0xb8(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb8(%rsp), %eax
movl %eax, 0x30(%rsp)
callq 0x138e0
movl %eax, %ecx
movl 0x30(%rsp), %eax
cmpl %ecx, %eax
jge 0x59539
movl $0x0, 0xbc(%rsp)
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %eax
movl %eax, 0x2c(%rsp)
callq 0x138c0
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x59273
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
callq 0x6bad0
movsd 0xd9dcf(%rip), %xmm1    # 0x133010
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movslq %eax, %rdx
movq 0x88(%rsp), %rax
movslq 0xbc(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x591fb
movl $0x0, 0xb0(%rsp)
movl $0x0, 0xbc(%rsp)
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %eax
movl %eax, 0x28(%rsp)
callq 0x138c0
movl %eax, %ecx
movl 0x28(%rsp), %eax
cmpl %ecx, %eax
jge 0x593c4
movq 0x88(%rsp), %rax
movslq 0xbc(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0xa0(%rsp)
je 0x59384
movl 0xb0(%rsp), %eax
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %eax
cmpl 0xbc(%rsp), %eax
jg 0x59382
movq 0x88(%rsp), %rax
movslq 0xac(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xbc(%rsp), %ecx
subl 0xac(%rsp), %ecx
movl 0xbc(%rsp), %edx
subl 0xac(%rsp), %edx
imull %edx, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
cmpq 0xa0(%rsp), %rax
jg 0x5936a
movq 0x90(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl 0xac(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x5936c
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x592e5
jmp 0x59392
movl 0xbc(%rsp), %eax
movl %eax, 0xb0(%rsp)
movq 0xa0(%rsp), %rdx
movq 0x80(%rsp), %rax
movslq 0xbc(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x59289
movq 0x50(%rsp), %rdi
callq 0x138c0
movq 0x50(%rsp), %rdi
subl $0x1, %eax
movl %eax, 0xb0(%rsp)
callq 0x138c0
subl $0x1, %eax
movl %eax, 0xbc(%rsp)
cmpl $0x0, 0xbc(%rsp)
jl 0x59521
movq 0x80(%rsp), %rax
movslq 0xbc(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0xa0(%rsp)
je 0x594fb
movl 0xb0(%rsp), %eax
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %eax
cmpl 0xbc(%rsp), %eax
jl 0x594d0
movq 0x88(%rsp), %rax
movslq 0xac(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xbc(%rsp), %ecx
subl 0xac(%rsp), %ecx
movl 0xbc(%rsp), %edx
subl 0xac(%rsp), %edx
imull %edx, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
cmpq 0xa0(%rsp), %rax
jg 0x594b8
movq 0x90(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl 0xac(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x594ba
movl 0xac(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x59433
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
cvtsi2sdq 0xa0(%rsp), %xmm0
callq 0x6bc60
jmp 0x59509
movl 0xbc(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x5950b
movl 0xbc(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x593ec
jmp 0x59523
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x591cd
jmp 0x5953b
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x5919f
movl $0x0, 0xb4(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb4(%rsp), %eax
movl %eax, 0x24(%rsp)
callq 0x13900
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x5990e
movl $0x0, 0xbc(%rsp)
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %eax
movl %eax, 0x20(%rsp)
callq 0x138c0
movl %eax, %ecx
movl 0x20(%rsp), %eax
cmpl %ecx, %eax
jge 0x598f6
movl $0x0, 0xb8(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb8(%rsp), %eax
movl %eax, 0x1c(%rsp)
callq 0x138e0
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x59630
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
callq 0x6bad0
movsd 0xd9a12(%rip), %xmm1    # 0x133010
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movslq %eax, %rdx
movq 0x88(%rsp), %rax
movslq 0xb8(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x595b8
movl $0x0, 0xb0(%rsp)
movl $0x0, 0xb8(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb8(%rsp), %eax
movl %eax, 0x18(%rsp)
callq 0x138e0
movl %eax, %ecx
movl 0x18(%rsp), %eax
cmpl %ecx, %eax
jge 0x59781
movq 0x88(%rsp), %rax
movslq 0xb8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0xa0(%rsp)
je 0x59741
movl 0xb0(%rsp), %eax
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %eax
cmpl 0xb8(%rsp), %eax
jg 0x5973f
movq 0x88(%rsp), %rax
movslq 0xac(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xb8(%rsp), %ecx
subl 0xac(%rsp), %ecx
movl 0xb8(%rsp), %edx
subl 0xac(%rsp), %edx
imull %edx, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
cmpq 0xa0(%rsp), %rax
jg 0x59727
movq 0x90(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl 0xac(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x59729
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x596a2
jmp 0x5974f
movl 0xb8(%rsp), %eax
movl %eax, 0xb0(%rsp)
movq 0xa0(%rsp), %rdx
movq 0x80(%rsp), %rax
movslq 0xb8(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x59646
movq 0x50(%rsp), %rdi
callq 0x138e0
movq 0x50(%rsp), %rdi
subl $0x1, %eax
movl %eax, 0xb0(%rsp)
callq 0x138e0
subl $0x1, %eax
movl %eax, 0xb8(%rsp)
cmpl $0x0, 0xb8(%rsp)
jl 0x598de
movq 0x80(%rsp), %rax
movslq 0xb8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0xa0(%rsp)
je 0x598b8
movl 0xb0(%rsp), %eax
movl %eax, 0xac(%rsp)
movl 0xac(%rsp), %eax
cmpl 0xb8(%rsp), %eax
jle 0x5988d
movq 0x88(%rsp), %rax
movslq 0xac(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xb8(%rsp), %ecx
subl 0xac(%rsp), %ecx
movl 0xb8(%rsp), %edx
subl 0xac(%rsp), %edx
imull %edx, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
cmpq 0xa0(%rsp), %rax
jg 0x59875
movq 0x90(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl 0xac(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x59877
movl 0xac(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x597f0
movq 0x50(%rsp), %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
movl 0xb4(%rsp), %ecx
cvtsi2sdq 0xa0(%rsp), %xmm0
callq 0x6bc60
jmp 0x598c6
movl 0xb8(%rsp), %eax
movl %eax, 0xb0(%rsp)
jmp 0x598c8
movl 0xb8(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x597a9
jmp 0x598e0
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x5958a
jmp 0x598f8
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x5955c
movq 0x88(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x5992b
movq 0x10(%rsp), %rdi
callq 0xf670
movq 0x80(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x59948
movq 0x8(%rsp), %rdi
callq 0xf670
addq $0xc8, %rsp
retq