// File: tomfunkhouser[P]gaps/apps/msh2grd/msh2grd.cpp
// Function: CreateGrid(gaps::R3Mesh*)
static R3Grid *
CreateGrid(R3Mesh *mesh)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();

  // Allocate grid
  R3Grid *grid = new R3Grid(mesh->BBox(), grid_spacing, min_resolution, max_resolution);
  if (!grid) {
    RNFail("Unable to allocate grid\n");
    exit(-1);
  }

  // Rasterize mesh
  if (mesh->NFaces() == 0) {
    // Rasterize each vertex into grid
    for (int i = 0; i < mesh->NVertices(); i++) {
      R3MeshVertex *vertex = mesh->Vertex(i);
      const R3Point& p = mesh->VertexPosition(vertex);
      grid->RasterizeWorldPoint(p, 1.0);
    }
  }
  else {
    // Rasterize each triangle into grid
    for (int i = 0; i < mesh->NFaces(); i++) {
      R3MeshFace *face = mesh->Face(i);
      const R3Point& p0 = mesh->VertexPosition(mesh->VertexOnFace(face, 0));
      const R3Point& p1 = mesh->VertexPosition(mesh->VertexOnFace(face, 1));
      const R3Point& p2 = mesh->VertexPosition(mesh->VertexOnFace(face, 2));
      grid->RasterizeWorldTriangle(p0, p1, p2, 1.0);
    }
  }

  // Make binary (in case triangles overlap)
  grid->Threshold(0.5, 0, 1);

  // Check if should compute sdf
  if (sdf) {
    // Compute distance grid
    grid->SquaredDistanceTransform();
    grid->Sqrt();
    grid->Multiply(grid->GridToWorldScaleFactor());

    // Allocate temmporary memory
    int *votes = new int [ grid->NEntries() ];
    int *components = new int [ grid->NEntries() ];
    for (int i = 0; i < grid->NEntries(); i++) votes[i] = 0;
    for (int i = 0; i < grid->NEntries(); i++) components[i] = 0;

    // Vote for signs by connected component
    R3Grid signs(*grid);
    signs.Clear(0);
    for (int i = 0; i < mesh->NFaces(); i++) {
      R3MeshFace *face = mesh->Face(i);
      RNLength e = ShortestEdgeLength(mesh, face);
      if (e > grid_spacing) e = grid_spacing;
      R3Point p = mesh->FaceCentroid(face);
      R3Point p1 = p + e * mesh->FaceNormal(face);
      R3Point p2 = p - e * mesh->FaceNormal(face);
      signs.RasterizeWorldPoint(p1, 1.0);
      signs.RasterizeWorldPoint(p2, -1.0);
    }

    // Vote for connected components
    int ncomponents = grid->ConnectedComponents(0, grid->NEntries(), NULL, NULL, components);
    if (ncomponents > 0) {
      for (int i = 0; i < grid->NEntries(); i++) {
        int component = components[i];
        if (component < 0) continue;
        votes[component] += signs.GridValue(i);
      }

      // Set signs by votes on connected components
      for (int i = 0; i < grid->NEntries(); i++) {
        int component = components[i];
        if (component < 0) continue;
        if (votes[component] < 0) {
          RNScalar d = grid->GridValue(i);
          grid->SetGridValue(i, -d);
        }
      }
    }
    
    // Delete temporary memory
    delete [] components;
    delete [] votes;
  }

  // Print statistics
  if (print_verbose) {
    printf("Created grid ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  Resolution = %d %d %d\n", grid->XResolution(), grid->YResolution(), grid->ZResolution());
    printf("  Spacing = %g\n", grid->GridToWorldScaleFactor());
    printf("  Cardinality = %d\n", grid->Cardinality());
    printf("  Volume = %g\n", grid->Volume());
    RNInterval grid_range = grid->Range();
    printf("  Minimum = %g\n", grid_range.Min());
    printf("  Maximum = %g\n", grid_range.Max());
    printf("  L1Norm = %g\n", grid->L1Norm());
    printf("  L2Norm = %g\n", grid->L2Norm());
    fflush(stdout);
  }

  // Return grid
  return grid;
}

// Assembly:
subq $0x468, %rsp            # imm = 0x468
movq %rdi, 0x460(%rsp)
leaq 0x450(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
callq 0xd0d10
movq 0xc0(%rsp), %rdi
callq 0x13580
movl $0x250, %edi            # imm = 0x250
callq 0xf4c0
movq %rax, 0xc8(%rsp)
movq 0x460(%rsp), %rdi
callq 0x13610
movq %rax, 0xd0(%rsp)
jmp 0x1297a
movq 0xd0(%rsp), %rsi
movq 0xc8(%rsp), %rdi
movsd 0x15cb6e(%rip), %xmm0   # 0x16f500
movl 0x15cb70(%rip), %edx    # 0x16f508
movl 0x15cb6e(%rip), %ecx    # 0x16f50c
xorl %r8d, %r8d
callq 0x55e30
jmp 0x129a8
movq 0xc8(%rsp), %rax
movq %rax, 0x448(%rsp)
cmpq $0x0, 0x448(%rsp)
jne 0x12a06
leaq 0x120741(%rip), %rdi    # 0x13310b
movb $0x0, %al
callq 0xd4f30
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0xf600
movq 0xc8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x440(%rsp)
movl %eax, 0x43c(%rsp)
movl $0x250, %esi            # imm = 0x250
callq 0xf4d0
jmp 0x133b5
movq 0x460(%rsp), %rdi
callq 0x135a0
cmpl $0x0, %eax
jne 0x12ac2
movl $0x0, 0x438(%rsp)
movl 0x438(%rsp), %eax
movl %eax, 0xbc(%rsp)
movq 0x460(%rsp), %rdi
callq 0x135e0
movl %eax, %ecx
movl 0xbc(%rsp), %eax
cmpl %ecx, %eax
jge 0x12abd
movq 0x460(%rsp), %rdi
movl 0x438(%rsp), %esi
callq 0x13630
movq %rax, 0x430(%rsp)
movq 0x460(%rsp), %rdi
movq 0x430(%rsp), %rsi
callq 0x13660
movq %rax, 0x428(%rsp)
movq 0x448(%rsp), %rdi
movq 0x428(%rsp), %rsi
movsd 0x120568(%rip), %xmm0   # 0x133008
xorl %edx, %edx
callq 0x13680
movl 0x438(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x438(%rsp)
jmp 0x12a27
jmp 0x12c20
movl $0x0, 0x424(%rsp)
movl 0x424(%rsp), %eax
movl %eax, 0xb8(%rsp)
movq 0x460(%rsp), %rdi
callq 0x135a0
movl %eax, %ecx
movl 0xb8(%rsp), %eax
cmpl %ecx, %eax
jge 0x12c1e
movq 0x460(%rsp), %rdi
movl 0x424(%rsp), %esi
callq 0x136d0
movq %rax, 0x418(%rsp)
movq 0x460(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0x460(%rsp), %rdi
movq 0x418(%rsp), %rsi
xorl %edx, %edx
callq 0x13700
movq 0xa0(%rsp), %rdi
movq %rax, %rsi
callq 0x13660
movq %rax, 0x410(%rsp)
movq 0x460(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0x460(%rsp), %rdi
movq 0x418(%rsp), %rsi
movl $0x1, %edx
callq 0x13700
movq 0xa8(%rsp), %rdi
movq %rax, %rsi
callq 0x13660
movq %rax, 0x408(%rsp)
movq 0x460(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0x460(%rsp), %rdi
movq 0x418(%rsp), %rsi
movl $0x2, %edx
callq 0x13700
movq 0xb0(%rsp), %rdi
movq %rax, %rsi
callq 0x13660
movq %rax, 0x400(%rsp)
movq 0x448(%rsp), %rdi
movq 0x410(%rsp), %rsi
movq 0x408(%rsp), %rdx
movq 0x400(%rsp), %rcx
movsd 0x120408(%rip), %xmm0   # 0x133008
xorl %r8d, %r8d
callq 0x13720
movl 0x424(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x424(%rsp)
jmp 0x12acd
jmp 0x12c20
movq 0x448(%rsp), %rdi
movsd 0x1203e0(%rip), %xmm0   # 0x133010
xorps %xmm1, %xmm1
movsd 0x1203cd(%rip), %xmm2   # 0x133008
callq 0x59950
cmpl $0x0, 0x165935(%rip)    # 0x17857c
je 0x13247
movq 0x448(%rsp), %rdi
callq 0x58d20
movq 0x448(%rsp), %rdi
callq 0x588e0
movq 0x448(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x448(%rsp), %rdi
callq 0x137c0
movq 0x98(%rsp), %rdi
callq 0x5cf30
movq 0x448(%rsp), %rdi
callq 0x137e0
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0x3f8(%rsp)
movq 0x448(%rsp), %rdi
callq 0x137e0
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0x3f0(%rsp)
movl $0x0, 0x3ec(%rsp)
movl 0x3ec(%rsp), %eax
movl %eax, 0x94(%rsp)
movq 0x448(%rsp), %rdi
callq 0x137e0
movl %eax, %ecx
movl 0x94(%rsp), %eax
cmpl %ecx, %eax
jge 0x12d5e
movq 0x3f8(%rsp), %rax
movslq 0x3ec(%rsp), %rcx
movl $0x0, (%rax,%rcx,4)
movl 0x3ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3ec(%rsp)
jmp 0x12d0c
movl $0x0, 0x3e8(%rsp)
movl 0x3e8(%rsp), %eax
movl %eax, 0x90(%rsp)
movq 0x448(%rsp), %rdi
callq 0x137e0
movl %eax, %ecx
movl 0x90(%rsp), %eax
cmpl %ecx, %eax
jge 0x12dbb
movq 0x3f0(%rsp), %rax
movslq 0x3e8(%rsp), %rcx
movl $0x0, (%rax,%rcx,4)
movl 0x3e8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3e8(%rsp)
jmp 0x12d69
movq 0x448(%rsp), %rsi
leaq 0x198(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x568c0
movq 0x88(%rsp), %rdi
xorps %xmm0, %xmm0
callq 0x5c670
jmp 0x12dea
movl $0x0, 0x194(%rsp)
movl 0x194(%rsp), %eax
movl %eax, 0x80(%rsp)
movq 0x460(%rsp), %rdi
callq 0x135a0
movl %eax, 0x84(%rsp)
jmp 0x12e19
movl 0x80(%rsp), %eax
movl 0x84(%rsp), %ecx
cmpl %ecx, %eax
jge 0x13010
movq 0x460(%rsp), %rdi
movl 0x194(%rsp), %esi
callq 0x136d0
movq %rax, 0x78(%rsp)
jmp 0x12e4a
movq 0x78(%rsp), %rax
movq %rax, 0x188(%rsp)
movq 0x460(%rsp), %rdi
movq 0x188(%rsp), %rsi
callq 0x13470
movsd %xmm0, 0x70(%rsp)
jmp 0x12e74
movsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x180(%rsp)
movsd 0x180(%rsp), %xmm0
ucomisd 0x15c66c(%rip), %xmm0   # 0x16f500
jbe 0x12ecf
movsd 0x15c662(%rip), %xmm0   # 0x16f500
movsd %xmm0, 0x180(%rsp)
jmp 0x12ecf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x440(%rsp)
movl %eax, 0x43c(%rsp)
leaq 0x198(%rsp), %rdi
callq 0x56960
jmp 0x133b5
movq 0x460(%rsp), %rsi
movq 0x188(%rsp), %rdx
leaq 0x168(%rsp), %rdi
callq 0x14ff0
jmp 0x12eee
movsd 0x180(%rsp), %xmm0
movsd %xmm0, 0x60(%rsp)
movq 0x460(%rsp), %rdi
movq 0x188(%rsp), %rsi
callq 0x13840
movq %rax, 0x68(%rsp)
jmp 0x12f19
movq 0x68(%rsp), %rsi
movsd 0x60(%rsp), %xmm0
leaq 0x138(%rsp), %rdi
callq 0x13800
jmp 0x12f33
leaq 0x150(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x138(%rsp), %rdx
callq 0x6f110
jmp 0x12f52
movsd 0x180(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x460(%rsp), %rdi
movq 0x188(%rsp), %rsi
callq 0x13840
movq %rax, 0x58(%rsp)
jmp 0x12f7d
movq 0x58(%rsp), %rsi
movsd 0x50(%rsp), %xmm0
leaq 0x108(%rsp), %rdi
callq 0x13800
jmp 0x12f97
leaq 0x120(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x6fab0
jmp 0x12fb6
leaq 0x198(%rsp), %rdi
leaq 0x150(%rsp), %rsi
movsd 0x12003a(%rip), %xmm0   # 0x133008
xorl %edx, %edx
callq 0x13680
jmp 0x12fd7
leaq 0x198(%rsp), %rdi
leaq 0x120(%rsp), %rsi
movsd 0x120029(%rip), %xmm0   # 0x133018
xorl %edx, %edx
callq 0x13680
jmp 0x12ff8
jmp 0x12ffa
movl 0x194(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x194(%rsp)
jmp 0x12df5
movq 0x448(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x137e0
movl %eax, 0x4c(%rsp)
jmp 0x13028
movl 0x4c(%rsp), %esi
movq 0x40(%rsp), %rdi
movq 0x3f0(%rsp), %r8
xorl %eax, %eax
movl %eax, %ecx
xorps %xmm0, %xmm0
movq %rcx, %rdx
callq 0x68de0
movl %eax, 0x3c(%rsp)
jmp 0x1304e
movl 0x3c(%rsp), %eax
movl %eax, 0x104(%rsp)
cmpl $0x0, 0x104(%rsp)
jle 0x13200
movl $0x0, 0x100(%rsp)
movl 0x100(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x448(%rsp), %rdi
callq 0x137e0
movl %eax, 0x38(%rsp)
jmp 0x13090
movl 0x34(%rsp), %eax
movl 0x38(%rsp), %ecx
cmpl %ecx, %eax
jge 0x1311a
movq 0x3f0(%rsp), %rax
movslq 0x100(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0xfc(%rsp)
cmpl $0x0, 0xfc(%rsp)
jge 0x130c2
jmp 0x13104
movl 0x100(%rsp), %esi
leaq 0x198(%rsp), %rdi
callq 0x13870
movsd %xmm0, 0x28(%rsp)
jmp 0x130de
movsd 0x28(%rsp), %xmm1
movq 0x3f8(%rsp), %rax
movslq 0xfc(%rsp), %rcx
cvtsi2sdl (%rax,%rcx,4), %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %edx
movl %edx, (%rax,%rcx,4)
movl 0x100(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x100(%rsp)
jmp 0x13072
movl $0x0, 0xf8(%rsp)
movl 0xf8(%rsp), %eax
movl %eax, 0x20(%rsp)
movq 0x448(%rsp), %rdi
callq 0x137e0
movl %eax, 0x24(%rsp)
jmp 0x13143
movl 0x20(%rsp), %eax
movl 0x24(%rsp), %ecx
cmpl %ecx, %eax
jge 0x131fe
movq 0x3f0(%rsp), %rax
movslq 0xf8(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0xf4(%rsp)
cmpl $0x0, 0xf4(%rsp)
jge 0x13179
jmp 0x131e8
movq 0x3f8(%rsp), %rax
movslq 0xf4(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jge 0x131e6
movq 0x448(%rsp), %rdi
movl 0xf8(%rsp), %esi
callq 0x13870
movsd %xmm0, 0x18(%rsp)
jmp 0x131ab
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
movq 0x448(%rsp), %rdi
movl 0xf8(%rsp), %esi
movaps 0x11fe60(%rip), %xmm1   # 0x133030
movsd 0xe8(%rsp), %xmm0
pxor %xmm1, %xmm0
callq 0x13890
jmp 0x131e4
jmp 0x131e6
jmp 0x131e8
movl 0xf8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf8(%rsp)
jmp 0x13125
jmp 0x13200
movq 0x3f0(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x1321d
movq 0x10(%rsp), %rdi
callq 0xf670
movq 0x3f8(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x1323a
movq 0x8(%rsp), %rdi
callq 0xf670
leaq 0x198(%rsp), %rdi
callq 0x56960
cmpl $0x0, 0x16532a(%rip)    # 0x178578
je 0x133a5
leaq 0x11fec9(%rip), %rdi    # 0x133124
movb $0x0, %al
callq 0xf070
leaq 0x450(%rsp), %rdi
callq 0xd0dd0
leaq 0x11fe4b(%rip), %rdi    # 0x1330c1
movb $0x1, %al
callq 0xf070
movq 0x448(%rsp), %rdi
callq 0x138c0
movl %eax, (%rsp)
movq 0x448(%rsp), %rdi
callq 0x138e0
movl %eax, 0x4(%rsp)
movq 0x448(%rsp), %rdi
callq 0x13900
movl (%rsp), %esi
movl 0x4(%rsp), %edx
movl %eax, %ecx
leaq 0x11fe7b(%rip), %rdi    # 0x133136
movb $0x0, %al
callq 0xf070
movq 0x448(%rsp), %rdi
callq 0x137c0
leaq 0x11fe79(%rip), %rdi    # 0x13314f
movb $0x1, %al
callq 0xf070
movq 0x448(%rsp), %rdi
callq 0x56dc0
movl %eax, %esi
leaq 0x11fe6c(%rip), %rdi    # 0x13315f
movb $0x0, %al
callq 0xf070
movq 0x448(%rsp), %rdi
callq 0x13920
leaq 0x11fe65(%rip), %rdi    # 0x133173
movb $0x1, %al
callq 0xf070
movq 0x448(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x56bc0
leaq 0xd8(%rsp), %rdi
callq 0x13960
leaq 0x11fe44(%rip), %rdi    # 0x133182
movb $0x1, %al
callq 0xf070
leaq 0xd8(%rsp), %rdi
callq 0x13970
leaq 0x11fe39(%rip), %rdi    # 0x133192
movb $0x1, %al
callq 0xf070
movq 0x448(%rsp), %rdi
callq 0x56cb0
leaq 0x11fe2e(%rip), %rdi    # 0x1331a2
movb $0x1, %al
callq 0xf070
movq 0x448(%rsp), %rdi
callq 0x13980
leaq 0x11fe22(%rip), %rdi    # 0x1331b1
movb $0x1, %al
callq 0xf070
movq 0x15bbf3(%rip), %rax    # 0x16ef90
movq (%rax), %rdi
callq 0xf5d0
movq 0x448(%rsp), %rax
addq $0x468, %rsp            # imm = 0x468
retq
movq 0x440(%rsp), %rdi
callq 0xf890
nopw %cs:(%rax,%rax)