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

  // Get convenient variables
  RNLength grid_spacing = grid->GridToWorldScaleFactor();

  // Rasterize negative sides of faces
  for (int i = 0; i < mesh->NFaces(); i++) {
    R3MeshFace *face = mesh->Face(i);
    R3Vector n = grid_spacing * mesh->FaceNormal(face);
    R3MeshVertex *v0 = mesh->VertexOnFace(face, 0);
    R3MeshVertex *v1 = mesh->VertexOnFace(face, 1);
    R3MeshVertex *v2 = mesh->VertexOnFace(face, 2);
    R3Point p0 = mesh->VertexPosition(v0);
    R3Point p1 = mesh->VertexPosition(v1);
    R3Point p2 = mesh->VertexPosition(v2);
    sign_grid.RasterizeWorldTriangle(p0 - n, p1 - n, p2 - n, -1.0, R3_GRID_REPLACE_OPERATION);
  }

  // Rasterize positive sides of faces (overwrite negatives if collisions)
  for (int i = 0; i < mesh->NFaces(); i++) {
    R3MeshFace *face = mesh->Face(i);
    R3Vector n = grid_spacing * mesh->FaceNormal(face);
    R3MeshVertex *v0 = mesh->VertexOnFace(face, 0);
    R3MeshVertex *v1 = mesh->VertexOnFace(face, 1);
    R3MeshVertex *v2 = mesh->VertexOnFace(face, 2);
    R3Point p0 = mesh->VertexPosition(v0);
    R3Point p1 = mesh->VertexPosition(v1);
    R3Point p2 = mesh->VertexPosition(v2);
    R3Vector n0 = grid_spacing * mesh->VertexNormal(v0);
    R3Vector n1 = grid_spacing * mesh->VertexNormal(v1);
    R3Vector n2 = grid_spacing * mesh->VertexNormal(v2);
    sign_grid.RasterizeWorldTriangle(p0, p1, p2, 1.0, R3_GRID_REPLACE_OPERATION);
    sign_grid.RasterizeWorldTriangle(p0 + n, p1 + n, p2 + n, 1.0, R3_GRID_REPLACE_OPERATION);
    sign_grid.RasterizeWorldTriangle(p0 + 0.5*n, p1 + 0.5*n, p2 + 0.5*n, 1.0, R3_GRID_REPLACE_OPERATION);
    sign_grid.RasterizeWorldTriangle(p0 + 1.5*n, p1 + 1.5*n, p2 + 1.5*n, 1.0, R3_GRID_REPLACE_OPERATION);
    sign_grid.RasterizeWorldTriangle(p0 + n0, p1 + n1, p2 + n2, 1.0, R3_GRID_REPLACE_OPERATION);
    sign_grid.RasterizeWorldTriangle(p0 + 0.5*n0, p1 + 0.5*n1, p2 + 0.5*n2, 1.0, R3_GRID_REPLACE_OPERATION);
    sign_grid.RasterizeWorldTriangle(p0 + 1.5*n0, p1 + 1.5*n1, p2 + 1.5*n2, 1.0, R3_GRID_REPLACE_OPERATION);
  }

  // Flood fill signs
  sign_grid.Voronoi();

  // Apply signs
  sign_grid.Threshold(0, -1, 1);
  grid->Multiply(sign_grid);

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

// Assembly:
subq $0x768, %rsp            # imm = 0x768
movq %rdi, 0x760(%rsp)
movq %rsi, 0x758(%rsp)
movq 0x760(%rsp), %rsi
leaq 0x508(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x7acf0
movq 0x78(%rsp), %rdi
xorps %xmm0, %xmm0
callq 0x80aa0
jmp 0x16150
movq 0x760(%rsp), %rdi
callq 0x17b20
movsd %xmm0, 0x4f0(%rsp)
movl $0x0, 0x4ec(%rsp)
movl 0x4ec(%rsp), %eax
movl %eax, 0x70(%rsp)
movq 0x758(%rsp), %rdi
callq 0x17880
movl %eax, 0x74(%rsp)
jmp 0x1618f
movl 0x70(%rsp), %eax
movl 0x74(%rsp), %ecx
cmpl %ecx, %eax
jge 0x163b4
movq 0x758(%rsp), %rdi
movl 0x4ec(%rsp), %esi
callq 0x17a10
movq %rax, 0x68(%rsp)
jmp 0x161ba
movq 0x68(%rsp), %rax
movq %rax, 0x4e0(%rsp)
movsd 0x4f0(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movq 0x758(%rsp), %rdi
movq 0x4e0(%rsp), %rsi
callq 0x17fd0
movq %rax, 0x60(%rsp)
jmp 0x161f2
movq 0x60(%rsp), %rsi
movsd 0x58(%rsp), %xmm0
leaq 0x4c8(%rsp), %rdi
callq 0x17f90
jmp 0x1620c
movq 0x758(%rsp), %rdi
movq 0x4e0(%rsp), %rsi
xorl %edx, %edx
callq 0x17a60
movq %rax, 0x4c0(%rsp)
movq 0x758(%rsp), %rdi
movq 0x4e0(%rsp), %rsi
movl $0x1, %edx
callq 0x17a60
movq %rax, 0x4b8(%rsp)
movq 0x758(%rsp), %rdi
movq 0x4e0(%rsp), %rsi
movl $0x2, %edx
callq 0x17a60
movq %rax, 0x4b0(%rsp)
movq 0x758(%rsp), %rdi
movq 0x4c0(%rsp), %rsi
callq 0x17a40
movq %rax, %rsi
leaq 0x498(%rsp), %rdi
callq 0x92f50
jmp 0x16296
movq 0x758(%rsp), %rdi
movq 0x4b8(%rsp), %rsi
callq 0x17a40
movq %rax, %rsi
leaq 0x480(%rsp), %rdi
callq 0x92f50
jmp 0x162bd
movq 0x758(%rsp), %rdi
movq 0x4b0(%rsp), %rsi
callq 0x17a40
movq %rax, %rsi
leaq 0x468(%rsp), %rdi
callq 0x92f50
jmp 0x162e4
leaq 0x450(%rsp), %rdi
leaq 0x498(%rsp), %rsi
leaq 0x4c8(%rsp), %rdx
callq 0x93e70
jmp 0x16303
leaq 0x438(%rsp), %rdi
leaq 0x480(%rsp), %rsi
leaq 0x4c8(%rsp), %rdx
callq 0x93e70
jmp 0x16322
leaq 0x420(%rsp), %rdi
leaq 0x468(%rsp), %rsi
leaq 0x4c8(%rsp), %rdx
callq 0x93e70
jmp 0x16341
leaq 0x508(%rsp), %rdi
leaq 0x450(%rsp), %rsi
leaq 0x438(%rsp), %rdx
leaq 0x420(%rsp), %rcx
movsd 0x129cdf(%rip), %xmm0   # 0x140048
movl $0x2, %r8d
callq 0x17a80
jmp 0x16376
jmp 0x16378
movl 0x4ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4ec(%rsp)
jmp 0x16171
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x500(%rsp)
movl %eax, 0x4fc(%rsp)
leaq 0x508(%rsp), %rdi
callq 0x7ad90
jmp 0x16b94
movl $0x0, 0x41c(%rsp)
movl 0x41c(%rsp), %eax
movl %eax, 0x50(%rsp)
movq 0x758(%rsp), %rdi
callq 0x17880
movl %eax, 0x54(%rsp)
jmp 0x163dd
movl 0x50(%rsp), %eax
movl 0x54(%rsp), %ecx
cmpl %ecx, %eax
jge 0x16b2e
movq 0x758(%rsp), %rdi
movl 0x41c(%rsp), %esi
callq 0x17a10
movq %rax, 0x48(%rsp)
jmp 0x16408
movq 0x48(%rsp), %rax
movq %rax, 0x410(%rsp)
movsd 0x4f0(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x758(%rsp), %rdi
movq 0x410(%rsp), %rsi
callq 0x17fd0
movq %rax, 0x40(%rsp)
jmp 0x16440
movq 0x40(%rsp), %rsi
movsd 0x38(%rsp), %xmm0
leaq 0x3f8(%rsp), %rdi
callq 0x17f90
jmp 0x1645a
movq 0x758(%rsp), %rdi
movq 0x410(%rsp), %rsi
xorl %edx, %edx
callq 0x17a60
movq %rax, 0x3f0(%rsp)
movq 0x758(%rsp), %rdi
movq 0x410(%rsp), %rsi
movl $0x1, %edx
callq 0x17a60
movq %rax, 0x3e8(%rsp)
movq 0x758(%rsp), %rdi
movq 0x410(%rsp), %rsi
movl $0x2, %edx
callq 0x17a60
movq %rax, 0x3e0(%rsp)
movq 0x758(%rsp), %rdi
movq 0x3f0(%rsp), %rsi
callq 0x17a40
movq %rax, %rsi
leaq 0x3c8(%rsp), %rdi
callq 0x92f50
jmp 0x164e4
movq 0x758(%rsp), %rdi
movq 0x3e8(%rsp), %rsi
callq 0x17a40
movq %rax, %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x92f50
jmp 0x1650b
movq 0x758(%rsp), %rdi
movq 0x3e0(%rsp), %rsi
callq 0x17a40
movq %rax, %rsi
leaq 0x398(%rsp), %rdi
callq 0x92f50
jmp 0x16532
movsd 0x4f0(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x758(%rsp), %rdi
movq 0x3f0(%rsp), %rsi
callq 0x18000
movq %rax, 0x30(%rsp)
jmp 0x1655d
movq 0x30(%rsp), %rsi
movsd 0x28(%rsp), %xmm0
leaq 0x380(%rsp), %rdi
callq 0x17f90
jmp 0x16577
movsd 0x4f0(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x758(%rsp), %rdi
movq 0x3e8(%rsp), %rsi
callq 0x18000
movq %rax, 0x20(%rsp)
jmp 0x165a2
movq 0x20(%rsp), %rsi
movsd 0x18(%rsp), %xmm0
leaq 0x368(%rsp), %rdi
callq 0x17f90
jmp 0x165bc
movsd 0x4f0(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x758(%rsp), %rdi
movq 0x3e0(%rsp), %rsi
callq 0x18000
movq %rax, 0x10(%rsp)
jmp 0x165e7
movq 0x10(%rsp), %rsi
movsd 0x8(%rsp), %xmm0
leaq 0x350(%rsp), %rdi
callq 0x17f90
jmp 0x16601
leaq 0x508(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0x3b0(%rsp), %rdx
leaq 0x398(%rsp), %rcx
movsd 0x129a27(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x16636
leaq 0x338(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0x3f8(%rsp), %rdx
callq 0x934d0
jmp 0x16655
leaq 0x320(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0x3f8(%rsp), %rdx
callq 0x934d0
jmp 0x16674
leaq 0x308(%rsp), %rdi
leaq 0x398(%rsp), %rsi
leaq 0x3f8(%rsp), %rdx
callq 0x934d0
jmp 0x16693
leaq 0x508(%rsp), %rdi
leaq 0x338(%rsp), %rsi
leaq 0x320(%rsp), %rdx
leaq 0x308(%rsp), %rcx
movsd 0x129995(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x166c8
leaq 0x2d8(%rsp), %rdi
movsd 0x129948(%rip), %xmm0   # 0x140020
leaq 0x3f8(%rsp), %rsi
callq 0x17f90
jmp 0x166e7
leaq 0x2f0(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0x2d8(%rsp), %rdx
callq 0x934d0
jmp 0x16706
leaq 0x2a8(%rsp), %rdi
movsd 0x12990a(%rip), %xmm0   # 0x140020
leaq 0x3f8(%rsp), %rsi
callq 0x17f90
jmp 0x16725
leaq 0x2c0(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0x2a8(%rsp), %rdx
callq 0x934d0
jmp 0x16744
leaq 0x278(%rsp), %rdi
movsd 0x1298cc(%rip), %xmm0   # 0x140020
leaq 0x3f8(%rsp), %rsi
callq 0x17f90
jmp 0x16763
leaq 0x290(%rsp), %rdi
leaq 0x398(%rsp), %rsi
leaq 0x278(%rsp), %rdx
callq 0x934d0
jmp 0x16782
leaq 0x508(%rsp), %rdi
leaq 0x2f0(%rsp), %rsi
leaq 0x2c0(%rsp), %rdx
leaq 0x290(%rsp), %rcx
movsd 0x1298a6(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x167b7
leaq 0x248(%rsp), %rdi
movsd 0x129891(%rip), %xmm0   # 0x140058
leaq 0x3f8(%rsp), %rsi
callq 0x17f90
jmp 0x167d6
leaq 0x260(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0x248(%rsp), %rdx
callq 0x934d0
jmp 0x167f5
leaq 0x218(%rsp), %rdi
movsd 0x129853(%rip), %xmm0   # 0x140058
leaq 0x3f8(%rsp), %rsi
callq 0x17f90
jmp 0x16814
leaq 0x230(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0x218(%rsp), %rdx
callq 0x934d0
jmp 0x16833
leaq 0x1e8(%rsp), %rdi
movsd 0x129815(%rip), %xmm0   # 0x140058
leaq 0x3f8(%rsp), %rsi
callq 0x17f90
jmp 0x16852
leaq 0x200(%rsp), %rdi
leaq 0x398(%rsp), %rsi
leaq 0x1e8(%rsp), %rdx
callq 0x934d0
jmp 0x16871
leaq 0x508(%rsp), %rdi
leaq 0x260(%rsp), %rsi
leaq 0x230(%rsp), %rdx
leaq 0x200(%rsp), %rcx
movsd 0x1297b7(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x168a6
leaq 0x1d0(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0x380(%rsp), %rdx
callq 0x934d0
jmp 0x168c5
leaq 0x1b8(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0x368(%rsp), %rdx
callq 0x934d0
jmp 0x168e4
leaq 0x1a0(%rsp), %rdi
leaq 0x398(%rsp), %rsi
leaq 0x350(%rsp), %rdx
callq 0x934d0
jmp 0x16903
leaq 0x508(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
leaq 0x1b8(%rsp), %rdx
leaq 0x1a0(%rsp), %rcx
movsd 0x129725(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x16938
leaq 0x170(%rsp), %rdi
movsd 0x1296d8(%rip), %xmm0   # 0x140020
leaq 0x380(%rsp), %rsi
callq 0x17f90
jmp 0x16957
leaq 0x188(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0x170(%rsp), %rdx
callq 0x934d0
jmp 0x16976
leaq 0x140(%rsp), %rdi
movsd 0x12969a(%rip), %xmm0   # 0x140020
leaq 0x368(%rsp), %rsi
callq 0x17f90
jmp 0x16995
leaq 0x158(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0x140(%rsp), %rdx
callq 0x934d0
jmp 0x169b4
leaq 0x110(%rsp), %rdi
movsd 0x12965c(%rip), %xmm0   # 0x140020
leaq 0x350(%rsp), %rsi
callq 0x17f90
jmp 0x169d3
leaq 0x128(%rsp), %rdi
leaq 0x398(%rsp), %rsi
leaq 0x110(%rsp), %rdx
callq 0x934d0
jmp 0x169f2
leaq 0x508(%rsp), %rdi
leaq 0x188(%rsp), %rsi
leaq 0x158(%rsp), %rdx
leaq 0x128(%rsp), %rcx
movsd 0x129636(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x16a27
leaq 0xe0(%rsp), %rdi
movsd 0x129621(%rip), %xmm0   # 0x140058
leaq 0x380(%rsp), %rsi
callq 0x17f90
jmp 0x16a46
leaq 0xf8(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
leaq 0xe0(%rsp), %rdx
callq 0x934d0
jmp 0x16a65
leaq 0xb0(%rsp), %rdi
movsd 0x1295e3(%rip), %xmm0   # 0x140058
leaq 0x368(%rsp), %rsi
callq 0x17f90
jmp 0x16a84
leaq 0xc8(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0xb0(%rsp), %rdx
callq 0x934d0
jmp 0x16aa3
leaq 0x80(%rsp), %rdi
movsd 0x1295a5(%rip), %xmm0   # 0x140058
leaq 0x350(%rsp), %rsi
callq 0x17f90
jmp 0x16ac2
leaq 0x98(%rsp), %rdi
leaq 0x398(%rsp), %rsi
leaq 0x80(%rsp), %rdx
callq 0x934d0
jmp 0x16ae1
leaq 0x508(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
leaq 0xc8(%rsp), %rdx
leaq 0x98(%rsp), %rcx
movsd 0x129547(%rip), %xmm0   # 0x140050
movl $0x2, %r8d
callq 0x17a80
jmp 0x16b16
jmp 0x16b18
movl 0x41c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x41c(%rsp)
jmp 0x163bf
xorl %eax, %eax
movl %eax, %esi
leaq 0x508(%rsp), %rdi
callq 0x81780
jmp 0x16b41
leaq 0x508(%rsp), %rdi
xorps %xmm0, %xmm0
movsd 0x1294f4(%rip), %xmm1   # 0x140048
movsd 0x1294f4(%rip), %xmm2   # 0x140050
callq 0x7dd80
jmp 0x16b63
movq 0x760(%rsp), %rdi
leaq 0x508(%rsp), %rsi
callq 0x813d0
jmp 0x16b7a
leaq 0x508(%rsp), %rdi
callq 0x7ad90
movl $0x1, %eax
addq $0x768, %rsp            # imm = 0x768
retq
movq 0x500(%rsp), %rdi
callq 0xf890
nopw %cs:(%rax,%rax)