// File: tomfunkhouser[P]gaps/apps/msh2df/msh2df.cpp
// Function: EstimateSignUsingFloodFill(gaps::R3Grid*, gaps::R3Mesh*)
static int
EstimateSignUsingFloodFill(R3Grid *grid, R3Mesh *mesh)
{
  // Initialize the sign grid
  R3Grid sign_grid(*grid);
  sign_grid.Clear(0);

  // Get convenient variables
  RNArray<const RNScalar *> stack;
  const RNScalar *sign_grid_values = sign_grid.GridValues();
  RNLength grid_spacing = grid->GridToWorldScaleFactor();
  RNScalar max_grid_step = sqrt(3)*grid_spacing;
  int ix, iy, iz, grid_index;

  // Initialize mesh search tree
  R3MeshSearchTree search_tree(mesh);
  
  // Seed search with border voxels (assumed outside)
  for (int i = 0; i < sign_grid.XResolution(); i++) {
    for (int j = 0; j < sign_grid.YResolution(); j++) {
      for (int k = 0; k < sign_grid.ZResolution(); k++) {
        if ((i == 0) || (i == sign_grid.XResolution()-1) ||
            (j == 0) || (j == sign_grid.YResolution()-1) ||
            (k == 0) || (k == sign_grid.ZResolution()-1)) {
          if (grid->GridValue(i, j, k) < grid_spacing) continue;
          sign_grid.IndicesToIndex(i, j, k, grid_index);
          stack.Insert(&sign_grid_values[grid_index]);
          sign_grid.SetGridValue(grid_index, 1);
        }
      }
    }
  }

  // Flood fill
  while (!stack.IsEmpty()) {
    const RNScalar *sign_grid_valuep = stack.Tail(); stack.RemoveTail();
    int grid_index = sign_grid_valuep - sign_grid_values;
    assert((grid_index >= 0) && (grid_index < sign_grid.NEntries()));
    sign_grid.IndexToIndices(grid_index, ix, iy, iz);
    R3Point p0 = sign_grid.WorldPosition(ix, iy, iz);
    for (int dz = -1; dz <= 1; dz++) {
      int gz = iz + dz;
      if ((gz < 0) || (gz >= sign_grid.ZResolution())) continue;
      for (int dy = -1; dy <= 1; dy++) {
        int gy = iy + dy;
        if ((gy < 0) || (gy >= sign_grid.YResolution())) continue;
        for (int dx = -1; dx <= 1; dx++) {
          int gx = ix + dx;
          if ((gx < 0) || (gx >= sign_grid.XResolution())) continue;
          if (sign_grid.GridValue(gx, gy, gz) > 0) continue;

          // Check if could step through surface
          RNScalar d = grid->GridValue(ix, iy, iz);
          if (d < max_grid_step) {
            RNScalar grid_step = sqrt((dx*dx + dy*dy + dz*dz) * grid_spacing*grid_spacing);
            if (d < grid_step) {
              // Check if stepping through a surface
              RNBoolean blocked = FALSE;
              R3Point p1 = sign_grid.WorldPosition(gx, gy, gz);
              R3Point midpoint = 0.5*(p0 + p1);
              RNArray<R3MeshIntersection *> hits;
              search_tree.FindAll(midpoint, hits, 0, 0.5*max_grid_step);
              for (int k = 0; k < hits.NEntries(); k++) {
                R3MeshIntersection *hit = hits.Kth(k);
                R3Plane plane = mesh->FacePlane(hit->face);
                delete hit;
                RNScalar d0 = R3SignedDistance(plane, p0);
                RNScalar d1 = R3SignedDistance(plane, p1);
                if (RNIsNegativeOrZero(d0*d1)) {
                  for (int k1 = k+1; k1 < hits.NEntries(); k1++) delete hits[k1];
                  blocked = TRUE;
                  break;
                }
              }
              if (blocked) continue;
            }
          }
          
          // Mark cell as outside and continue DFS 
          sign_grid.IndicesToIndex(gx, gy, gz, grid_index);
          stack.Insert(&sign_grid_values[grid_index]);
          sign_grid.SetGridValue(grid_index, 1);
        }
      }
    }
  }
  
  // Apply signs
  sign_grid.Threshold(0, -1, 1);
  grid->Multiply(sign_grid);

#if 1
  // Write some debug info
  if (print_debug) sign_grid.WriteFile("sign.grd");
#endif
  
  // Return success
  return 1;
}

// Assembly:
subq $0x458, %rsp            # imm = 0x458
movq %rdi, 0x450(%rsp)
movq %rsi, 0x448(%rsp)
movq 0x450(%rsp), %rsi
leaq 0x1f8(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x7acf0
movq 0x88(%rsp), %rdi
xorps %xmm0, %xmm0
callq 0x80aa0
jmp 0x16bf6
leaq 0x1d8(%rsp), %rdi
callq 0x18190
jmp 0x16c05
leaq 0x1f8(%rsp), %rdi
callq 0x181a0
movq %rax, 0x80(%rsp)
jmp 0x16c1c
movq 0x80(%rsp), %rax
movq %rax, 0x1d0(%rsp)
movq 0x450(%rsp), %rdi
callq 0x17b20
movsd %xmm0, 0x1c8(%rsp)
movl $0x3, %edi
callq 0x181c0
movsd %xmm0, 0x78(%rsp)
jmp 0x16c54
movsd 0x78(%rsp), %xmm0
movsd 0x1c8(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x1c0(%rsp)
movq 0x448(%rsp), %rsi
leaq 0x198(%rsp), %rdi
callq 0x1b120
jmp 0x16c87
movl $0x0, 0x194(%rsp)
movl 0x194(%rsp), %eax
movl %eax, 0x74(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b40
movl %eax, %ecx
movl 0x74(%rsp), %eax
cmpl %ecx, %eax
jge 0x16eea
movl $0x0, 0x190(%rsp)
movl 0x190(%rsp), %eax
movl %eax, 0x70(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b60
movl %eax, %ecx
movl 0x70(%rsp), %eax
cmpl %ecx, %eax
jge 0x16ed2
movl $0x0, 0x18c(%rsp)
movl 0x18c(%rsp), %eax
movl %eax, 0x6c(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b80
movl %eax, %ecx
movl 0x6c(%rsp), %eax
cmpl %ecx, %eax
jge 0x16eba
cmpl $0x0, 0x194(%rsp)
je 0x16daf
movl 0x194(%rsp), %eax
movl %eax, 0x68(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b40
movl %eax, %ecx
movl 0x68(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x16daf
cmpl $0x0, 0x190(%rsp)
je 0x16daf
movl 0x190(%rsp), %eax
movl %eax, 0x64(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b60
movl %eax, %ecx
movl 0x64(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x16daf
cmpl $0x0, 0x18c(%rsp)
je 0x16daf
movl 0x18c(%rsp), %eax
movl %eax, 0x60(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b80
movl %eax, %ecx
movl 0x60(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x16ea2
movq 0x450(%rsp), %rdi
movl 0x194(%rsp), %esi
movl 0x190(%rsp), %edx
movl 0x18c(%rsp), %ecx
callq 0x17e80
movaps %xmm0, %xmm1
movsd 0x1c8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x16e1a
jmp 0x16ea4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1f0(%rsp)
movl %eax, 0x1ec(%rsp)
jmp 0x1764d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1f0(%rsp)
movl %eax, 0x1ec(%rsp)
jmp 0x17640
movl 0x194(%rsp), %esi
movl 0x190(%rsp), %edx
movl 0x18c(%rsp), %ecx
leaq 0x1f8(%rsp), %rdi
leaq 0x1b0(%rsp), %r8
callq 0x181e0
jmp 0x16e46
movq 0x1d0(%rsp), %rax
movslq 0x1b0(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x18220
jmp 0x16e69
movl 0x1b0(%rsp), %esi
leaq 0x1f8(%rsp), %rdi
movsd 0x1291d0(%rip), %xmm0   # 0x140050
callq 0x18250
jmp 0x16e87
jmp 0x16ea2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1f0(%rsp)
movl %eax, 0x1ec(%rsp)
jmp 0x17633
jmp 0x16ea4
movl 0x18c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18c(%rsp)
jmp 0x16cf4
jmp 0x16ebc
movl 0x190(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x190(%rsp)
jmp 0x16cc3
jmp 0x16ed4
movl 0x194(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x194(%rsp)
jmp 0x16c92
jmp 0x16eec
leaq 0x1d8(%rsp), %rdi
callq 0x177d0
movl %eax, 0x5c(%rsp)
jmp 0x16eff
movl 0x5c(%rsp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x16f14
jmp 0x1759a
leaq 0x1d8(%rsp), %rdi
callq 0x18280
movq %rax, 0x50(%rsp)
jmp 0x16f28
movq 0x50(%rsp), %rax
movq %rax, 0x180(%rsp)
leaq 0x1d8(%rsp), %rdi
callq 0x18290
jmp 0x16f44
movq 0x180(%rsp), %rax
movq 0x1d0(%rsp), %rcx
subq %rcx, %rax
shrq $0x3, %rax
movl %eax, 0x17c(%rsp)
movl 0x17c(%rsp), %esi
leaq 0x1f8(%rsp), %rdi
leaq 0x1bc(%rsp), %rdx
leaq 0x1b8(%rsp), %rcx
leaq 0x1b4(%rsp), %r8
callq 0x182b0
jmp 0x16f90
cvtsi2sdl 0x1bc(%rsp), %xmm0
cvtsi2sdl 0x1b8(%rsp), %xmm1
cvtsi2sdl 0x1b4(%rsp), %xmm2
leaq 0x160(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x87100
jmp 0x16fc2
movl $0xffffffff, 0x15c(%rsp) # imm = 0xFFFFFFFF
cmpl $0x1, 0x15c(%rsp)
jg 0x17595
movl 0x1b4(%rsp), %eax
addl 0x15c(%rsp), %eax
movl %eax, 0x158(%rsp)
cmpl $0x0, 0x158(%rsp)
jl 0x1701c
movl 0x158(%rsp), %eax
movl %eax, 0x4c(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b80
movl %eax, %ecx
movl 0x4c(%rsp), %eax
cmpl %ecx, %eax
jl 0x17021
jmp 0x1757f
movl $0xffffffff, 0x154(%rsp) # imm = 0xFFFFFFFF
cmpl $0x1, 0x154(%rsp)
jg 0x1757d
movl 0x1b8(%rsp), %eax
addl 0x154(%rsp), %eax
movl %eax, 0x150(%rsp)
cmpl $0x0, 0x150(%rsp)
jl 0x1707b
movl 0x150(%rsp), %eax
movl %eax, 0x48(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b60
movl %eax, %ecx
movl 0x48(%rsp), %eax
cmpl %ecx, %eax
jl 0x17080
jmp 0x17567
movl $0xffffffff, 0x14c(%rsp) # imm = 0xFFFFFFFF
cmpl $0x1, 0x14c(%rsp)
jg 0x17565
movl 0x1bc(%rsp), %eax
addl 0x14c(%rsp), %eax
movl %eax, 0x148(%rsp)
cmpl $0x0, 0x148(%rsp)
jl 0x170da
movl 0x148(%rsp), %eax
movl %eax, 0x44(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x17b40
movl %eax, %ecx
movl 0x44(%rsp), %eax
cmpl %ecx, %eax
jl 0x170df
jmp 0x1754f
movl 0x148(%rsp), %esi
movl 0x150(%rsp), %edx
movl 0x158(%rsp), %ecx
leaq 0x1f8(%rsp), %rdi
callq 0x17e80
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1710f
jmp 0x1754f
movq 0x450(%rsp), %rdi
movl 0x1bc(%rsp), %esi
movl 0x1b8(%rsp), %edx
movl 0x1b4(%rsp), %ecx
callq 0x17e80
movsd %xmm0, 0x140(%rsp)
movsd 0x140(%rsp), %xmm1
movsd 0x1c0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x174e0
movl 0x14c(%rsp), %eax
imull 0x14c(%rsp), %eax
movl 0x154(%rsp), %ecx
imull 0x154(%rsp), %ecx
addl %ecx, %eax
movl 0x15c(%rsp), %ecx
imull 0x15c(%rsp), %ecx
addl %ecx, %eax
cvtsi2sd %eax, %xmm0
mulsd 0x1c8(%rsp), %xmm0
mulsd 0x1c8(%rsp), %xmm0
callq 0xf390
movsd %xmm0, 0x138(%rsp)
movsd 0x140(%rsp), %xmm1
movsd 0x138(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x174de
movl $0x0, 0x134(%rsp)
cvtsi2sdl 0x148(%rsp), %xmm0
cvtsi2sdl 0x150(%rsp), %xmm1
cvtsi2sdl 0x158(%rsp), %xmm2
leaq 0x118(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x87100
jmp 0x17204
leaq 0xe8(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x118(%rsp), %rdx
callq 0x93e00
jmp 0x17223
leaq 0x100(%rsp), %rdi
movsd 0x128ded(%rip), %xmm0   # 0x140020
leaq 0xe8(%rsp), %rsi
callq 0x18320
jmp 0x17242
leaq 0xd8(%rsp), %rdi
callq 0x18360
jmp 0x17251
movsd 0x1c0(%rsp), %xmm1
movsd 0x128dbe(%rip), %xmm0   # 0x140020
mulsd %xmm0, %xmm1
xorl %eax, %eax
movl %eax, %r8d
leaq 0x198(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0xd8(%rsp), %rdx
xorps %xmm0, %xmm0
movq %r8, %rcx
callq 0x20050
jmp 0x17290
movl $0x0, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
movl %eax, 0x40(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x178e0
movl %eax, %ecx
movl 0x40(%rsp), %eax
cmpl %ecx, %eax
jge 0x1749e
movl 0xd4(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x18370
movq %rax, 0x38(%rsp)
jmp 0x172dc
movq 0x38(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0x448(%rsp), %rdi
movq 0xc8(%rsp), %rax
movq 0x18(%rax), %rsi
callq 0x18070
movq %rax, 0x30(%rsp)
jmp 0x17309
movq 0x30(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x90530
jmp 0x1731d
movq 0xc8(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0x1733f
movq 0x28(%rsp), %rdi
movl $0x40, %esi
callq 0xf4d0
leaq 0xa8(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x30850
movsd %xmm0, 0x20(%rsp)
jmp 0x1735c
movsd 0x20(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
leaq 0xa8(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x30850
movsd %xmm0, 0x18(%rsp)
jmp 0x17388
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x98(%rsp)
movsd 0xa0(%rsp), %xmm0
movsd 0x98(%rsp), %xmm1
mulsd %xmm1, %xmm0
leaq 0x16f13c(%rip), %rax    # 0x1864f0
movsd (%rax), %xmm1
callq 0x18390
movl %eax, 0x14(%rsp)
jmp 0x173c3
movl 0x14(%rsp), %eax
cmpl $0x0, %eax
je 0x17486
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
movl %eax, 0x10(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x178e0
movl %eax, %ecx
movl 0x10(%rsp), %eax
cmpl %ecx, %eax
jge 0x17479
movl 0x94(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x183c0
movq %rax, 0x8(%rsp)
jmp 0x1741e
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x1743e
movq (%rsp), %rdi
movl $0x40, %esi
callq 0xf4d0
jmp 0x17440
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x173e1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1f0(%rsp)
movl %eax, 0x1ec(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x183e0
jmp 0x17633
movl $0x1, 0x134(%rsp)
jmp 0x1749e
jmp 0x17488
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x1729b
cmpl $0x0, 0x134(%rsp)
je 0x174b5
movl $0x15, 0x90(%rsp)
jmp 0x174c0
movl $0x0, 0x90(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x183e0
movl 0x90(%rsp), %eax
testl %eax, %eax
je 0x174dc
jmp 0x174da
jmp 0x1754f
jmp 0x174de
jmp 0x174e0
movl 0x148(%rsp), %esi
movl 0x150(%rsp), %edx
movl 0x158(%rsp), %ecx
leaq 0x1f8(%rsp), %rdi
leaq 0x17c(%rsp), %r8
callq 0x181e0
jmp 0x1750c
movq 0x1d0(%rsp), %rax
movslq 0x17c(%rsp), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x18220
jmp 0x1752f
movl 0x17c(%rsp), %esi
leaq 0x1f8(%rsp), %rdi
movsd 0x128b0a(%rip), %xmm0   # 0x140050
callq 0x18250
jmp 0x1754d
jmp 0x1754f
movl 0x14c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14c(%rsp)
jmp 0x1708b
jmp 0x17567
movl 0x154(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x154(%rsp)
jmp 0x1702c
jmp 0x1757f
movl 0x15c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x15c(%rsp)
jmp 0x16fcd
jmp 0x16eec
leaq 0x1f8(%rsp), %rdi
xorps %xmm0, %xmm0
movsd 0x128a9b(%rip), %xmm1   # 0x140048
movsd 0x128a9b(%rip), %xmm2   # 0x140050
callq 0x7dd80
jmp 0x175bc
movq 0x450(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x813d0
jmp 0x175d3
cmpl $0x0, 0x16f022(%rip)    # 0x1865fc
je 0x175f4
leaq 0x128dd6(%rip), %rsi    # 0x1403b9
leaq 0x1f8(%rsp), %rdi
callq 0x8a2b0
jmp 0x175f2
jmp 0x175f4
movl $0x1, 0x90(%rsp)
leaq 0x198(%rsp), %rdi
callq 0x1b2e0
leaq 0x1d8(%rsp), %rdi
callq 0x183f0
leaq 0x1f8(%rsp), %rdi
callq 0x7ad90
movl $0x1, %eax
addq $0x458, %rsp            # imm = 0x458
retq
leaq 0x198(%rsp), %rdi
callq 0x1b2e0
leaq 0x1d8(%rsp), %rdi
callq 0x183f0
leaq 0x1f8(%rsp), %rdi
callq 0x7ad90
movq 0x1f0(%rsp), %rdi
callq 0xf890
nopw (%rax,%rax)