// File: tomfunkhouser[P]gaps/pkgs/RGBD/RGBDImage.cpp
// Function: gaps::RGBDImage::ComputeMesh(gaps::R3Mesh&, double, double)
int RGBDImage::
ComputeMesh(R3Mesh& mesh, RNLength max_depth, RNLength max_silhouette_factor)
{
  // Read the channels
  ReadChannels();

  // Allocate temporary array of vertex pointers
  int nvertices = NPixels(RN_X) * NPixels(RN_Y);
  R3MeshVertex **vertices = new R3MeshVertex * [ nvertices ];
  for (int i = 0; i < nvertices; i++) vertices[i] = NULL;

  // Compute boundary image ???
  R2Grid boundary_image(NPixels(RN_X), NPixels(RN_Y));
  if (!RGBDCreateBoundaryChannel(this, boundary_image, max_silhouette_factor)) return 0;
  boundary_image.Substitute(R2_GRID_UNKNOWN_VALUE, 0);
         
  // Create vertices
  for (int j = 0; j < NPixels(RN_Y); j++) {
    for (int i = 0; i < NPixels(RN_X); i++) {
      // Check depth
      RNScalar depth = PixelDepth(i, j);
      if (depth == R2_GRID_UNKNOWN_VALUE) continue;
      if (RNIsNegativeOrZero(depth)) continue;
      if ((max_depth > 0) && (depth > max_depth)) continue;

      // Check if on border ???
      unsigned int b = (unsigned int) (boundary_image.GridValue(i, j) + 0.5);
      if (b & RGBD_BORDER_BOUNDARY) continue;
      // if (b) continue; 
      
      // Compute vertex info
      R3Point position = PixelWorldPosition(i, j);
      RNRgb color = PixelColor(i, j);
      R2Point texcoords(i, j);

      // Create vertex
      int vertex_index = j*NPixels(RN_X) + i;
      vertices[vertex_index] = mesh.CreateVertex(position, R3zero_vector, color, texcoords);
    }
  }

  // Create faces
  for (int i = 0; i < NPixels(RN_X)-1; i++) {
    for (int j = 0; j < NPixels(RN_Y)-1; j++) {
      // Get vertices
      R3MeshVertex *v00 = vertices[(j+0)*NPixels(RN_X) + (i+0)];
      R3MeshVertex *v01 = vertices[(j+1)*NPixels(RN_X) + (i+0)];
      R3MeshVertex *v10 = vertices[(j+0)*NPixels(RN_X) + (i+1)];
      R3MeshVertex *v11 = vertices[(j+1)*NPixels(RN_X) + (i+1)];

      // Get boundary flags
      unsigned int b00 = (unsigned int) (boundary_image.GridValue(i, j) + 0.5);
      unsigned int b10 = (unsigned int) (boundary_image.GridValue(i+1, j) + 0.5);
      unsigned int b01 = (unsigned int) (boundary_image.GridValue(i, j+1) + 0.5);
      unsigned int b11 = (unsigned int) (boundary_image.GridValue(i+1, j+1) + 0.5);
      unsigned int bad_combination = RGBD_SILHOUETTE_BOUNDARY | RGBD_SHADOW_BOUNDARY;

      // Create faces
      if (!v00) {
        if (v10 && v11 && v01) {
          if (((b10 | b11 | b01) & bad_combination) != bad_combination) {
            mesh.CreateFace(v10, v11, v01);
          }
        }
      }
      else if (!v10) {
        if (v00 && v11 && v01) {
          if (((b00 | b11 | b01) & bad_combination) != bad_combination) {
            mesh.CreateFace(v00, v11, v01);
          }
        }
      }
      else if (!v01) {
        if (v00 && v10 && v11) {
          if (((b00 | b10 | b11) & bad_combination) != bad_combination) {
            mesh.CreateFace(v00, v10, v11);
          }
        }
      }
      else if (!v11) {
        if (v00 && v10 && v01) {
          if (((b00 | b10 | b01) & bad_combination) != bad_combination) {
            mesh.CreateFace(v00, v10, v01);
          }
        }
      }
      else {
        assert(v00 && v01 && v10 && v11);
        if (((b00 | b10 | b11) & bad_combination) != bad_combination) {
          mesh.CreateFace(v00, v10, v11);
        }
        if (((b00 | b11 | b01) & bad_combination) != bad_combination) {
          mesh.CreateFace(v00, v11, v01);
        }
      } 
    }
  }

  // Delete temporary array of vertex pointers
  delete [] vertices;

  // Release the channels
  ReleaseChannels();

  // Return success
  return 1;
}

// Assembly:
subq $0x298, %rsp            # imm = 0x298
movq %rdi, 0x288(%rsp)
movq %rsi, 0x280(%rsp)
movsd %xmm0, 0x278(%rsp)
movsd %xmm1, 0x270(%rsp)
movq 0x288(%rsp), %rdi
movq %rdi, 0xd0(%rsp)
movq (%rdi), %rax
callq *0xf8(%rax)
movq 0xd0(%rsp), %rdi
xorl %esi, %esi
callq 0x1af30
movq 0xd0(%rsp), %rdi
movl %eax, 0xd8(%rsp)
movl $0x1, %esi
callq 0x1af30
movl %eax, %ecx
movl 0xd8(%rsp), %eax
imull %ecx, %eax
movl %eax, 0x26c(%rsp)
movslq 0x26c(%rsp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x12040
movq %rax, 0x260(%rsp)
movl $0x0, 0x25c(%rsp)
movl 0x25c(%rsp), %eax
cmpl 0x26c(%rsp), %eax
jge 0x2f994
movq 0x260(%rsp), %rax
movslq 0x25c(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movl 0x25c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x25c(%rsp)
jmp 0x2f959
movq 0xd0(%rsp), %rdi
xorl %esi, %esi
callq 0x1af30
movq 0xd0(%rsp), %rdi
movl %eax, 0xbc(%rsp)
movl $0x1, %esi
callq 0x1af30
movl 0xbc(%rsp), %esi
movl %eax, %edx
leaq 0x188(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
callq 0xb1ee0
movq 0xd0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movsd 0x270(%rsp), %xmm0
callq 0x31130
movl %eax, 0xcc(%rsp)
jmp 0x2fa01
movl 0xcc(%rsp), %eax
cmpl $0x0, %eax
jne 0x2fa4e
movl $0x0, 0x294(%rsp)
movl $0x1, 0x178(%rsp)
jmp 0x30388
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x180(%rsp)
movl %eax, 0x17c(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xb3390
jmp 0x303a4
leaq 0x188(%rsp), %rdi
movsd 0x1365c2(%rip), %xmm0   # 0x166020
xorps %xmm1, %xmm1
callq 0xba150
jmp 0x2fa68
movl $0x0, 0x174(%rsp)
movq 0xd0(%rsp), %rdi
movl 0x174(%rsp), %eax
movl %eax, 0xb4(%rsp)
movl $0x1, %esi
callq 0x1af30
movl %eax, 0xb8(%rsp)
jmp 0x2fa9c
movl 0xb4(%rsp), %eax
movl 0xb8(%rsp), %ecx
cmpl %ecx, %eax
jge 0x2fd43
movl $0x0, 0x170(%rsp)
movq 0xd0(%rsp), %rdi
movl 0x170(%rsp), %eax
movl %eax, 0xac(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0xb0(%rsp)
jmp 0x2fae3
movl 0xac(%rsp), %eax
movl 0xb0(%rsp), %ecx
cmpl %ecx, %eax
jge 0x2fd2b
movq 0xd0(%rsp), %rdi
movl 0x170(%rsp), %esi
movl 0x174(%rsp), %edx
callq 0x30570
movsd %xmm0, 0xa0(%rsp)
jmp 0x2fb1f
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x168(%rsp)
movsd 0x168(%rsp), %xmm0
movsd 0x1364de(%rip), %xmm1   # 0x166020
ucomisd %xmm1, %xmm0
jne 0x2fb4f
jp 0x2fb4f
jmp 0x2fd15
movsd 0x168(%rsp), %xmm0
leaq 0x182361(%rip), %rax    # 0x1b1ec0
movsd (%rax), %xmm1
callq 0x1a3d0
movl %eax, 0x9c(%rsp)
jmp 0x2fb71
movl 0x9c(%rsp), %eax
cmpl $0x0, %eax
je 0x2fb82
jmp 0x2fd15
movsd 0x278(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2fbad
movsd 0x168(%rsp), %xmm0
ucomisd 0x278(%rsp), %xmm0
jbe 0x2fbad
jmp 0x2fd15
movl 0x170(%rsp), %esi
movl 0x174(%rsp), %edx
leaq 0x188(%rsp), %rdi
callq 0x1a060
movsd %xmm0, 0x90(%rsp)
jmp 0x2fbd3
movsd 0x90(%rsp), %xmm0
movsd 0x136444(%rip), %xmm1   # 0x166028
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, 0x164(%rsp)
movl 0x164(%rsp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x2fc08
jmp 0x2fd15
movq 0xd0(%rsp), %rsi
movl 0x170(%rsp), %edx
movl 0x174(%rsp), %ecx
leaq 0x148(%rsp), %rdi
callq 0x30840
jmp 0x2fc2d
movq 0xd0(%rsp), %rsi
movl 0x170(%rsp), %edx
movl 0x174(%rsp), %ecx
leaq 0x130(%rsp), %rdi
callq 0x29420
jmp 0x2fc52
cvtsi2sdl 0x170(%rsp), %xmm0
cvtsi2sdl 0x174(%rsp), %xmm1
leaq 0x120(%rsp), %rdi
callq 0xcfd80
jmp 0x2fc73
movq 0xd0(%rsp), %rdi
movl 0x174(%rsp), %eax
movl %eax, 0x88(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0x8c(%rsp)
jmp 0x2fc99
movl 0x8c(%rsp), %ecx
movl 0x88(%rsp), %eax
imull %ecx, %eax
movl 0x170(%rsp), %ecx
addl %ecx, %eax
movl %eax, 0x11c(%rsp)
movq 0x280(%rsp), %rdi
movq (%rdi), %rax
movq 0x38(%rax), %rax
leaq 0x1832c0(%rip), %rdx    # 0x1b2f90
xorl %ecx, %ecx
movl %ecx, %r9d
leaq 0x148(%rsp), %rsi
leaq 0x130(%rsp), %rcx
leaq 0x120(%rsp), %r8
callq *%rax
movq %rax, 0x80(%rsp)
jmp 0x2fcf9
movq 0x80(%rsp), %rdx
movq 0x260(%rsp), %rax
movslq 0x11c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0x170(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x170(%rsp)
jmp 0x2fabd
jmp 0x2fd2d
movl 0x174(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x174(%rsp)
jmp 0x2fa73
movl $0x0, 0x118(%rsp)
movq 0xd0(%rsp), %rdi
movl 0x118(%rsp), %eax
movl %eax, 0x78(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0x7c(%rsp)
jmp 0x2fd6e
movl 0x78(%rsp), %eax
movl 0x7c(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x3033f
movl $0x0, 0x114(%rsp)
movq 0xd0(%rsp), %rdi
movl 0x114(%rsp), %eax
movl %eax, 0x70(%rsp)
movl $0x1, %esi
callq 0x1af30
movl %eax, 0x74(%rsp)
jmp 0x2fdaf
movl 0x70(%rsp), %eax
movl 0x74(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x30327
movq 0xd0(%rsp), %rdi
movq 0x260(%rsp), %rax
movq %rax, 0x60(%rsp)
movl 0x114(%rsp), %eax
movl %eax, 0x68(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0x6c(%rsp)
jmp 0x2fdef
movq 0xd0(%rsp), %rdi
movq 0x60(%rsp), %rax
movl 0x6c(%rsp), %edx
movl 0x68(%rsp), %ecx
imull %edx, %ecx
movl 0x118(%rsp), %edx
addl %edx, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x108(%rsp)
movq 0x260(%rsp), %rax
movq %rax, 0x50(%rsp)
movl 0x114(%rsp), %eax
incl %eax
movl %eax, 0x58(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0x5c(%rsp)
jmp 0x2fe46
movq 0xd0(%rsp), %rdi
movq 0x50(%rsp), %rax
movl 0x5c(%rsp), %edx
movl 0x58(%rsp), %ecx
imull %edx, %ecx
movl 0x118(%rsp), %edx
addl %edx, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x100(%rsp)
movq 0x260(%rsp), %rax
movq %rax, 0x40(%rsp)
movl 0x114(%rsp), %eax
movl %eax, 0x48(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0x4c(%rsp)
jmp 0x2fe9b
movq 0xd0(%rsp), %rdi
movq 0x40(%rsp), %rax
movl 0x4c(%rsp), %ecx
movl 0x48(%rsp), %esi
imull %ecx, %esi
movl 0x118(%rsp), %edx
movl %edx, %ecx
movl %esi, %edx
leal 0x1(%rcx,%rdx), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xf8(%rsp)
movq 0x260(%rsp), %rax
movq %rax, 0x30(%rsp)
movl 0x114(%rsp), %eax
incl %eax
movl %eax, 0x38(%rsp)
xorl %esi, %esi
callq 0x1af30
movl %eax, 0x3c(%rsp)
jmp 0x2fef8
movq 0x30(%rsp), %rax
movl 0x3c(%rsp), %ecx
movl 0x38(%rsp), %esi
imull %ecx, %esi
movl 0x118(%rsp), %edx
movl %edx, %ecx
movl %esi, %edx
leal 0x1(%rcx,%rdx), %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xf0(%rsp)
movl 0x118(%rsp), %esi
movl 0x114(%rsp), %edx
leaq 0x188(%rsp), %rdi
callq 0x1a060
movsd %xmm0, 0x28(%rsp)
jmp 0x2ff49
movsd 0x28(%rsp), %xmm0
movsd 0x1360d1(%rip), %xmm1   # 0x166028
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, 0xec(%rsp)
movl 0x118(%rsp), %esi
incl %esi
movl 0x114(%rsp), %edx
leaq 0x188(%rsp), %rdi
callq 0x1a060
movsd %xmm0, 0x20(%rsp)
jmp 0x2ff8c
movsd 0x20(%rsp), %xmm0
movsd 0x13608e(%rip), %xmm1   # 0x166028
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, 0xe8(%rsp)
movl 0x118(%rsp), %esi
movl 0x114(%rsp), %edx
incl %edx
leaq 0x188(%rsp), %rdi
callq 0x1a060
movsd %xmm0, 0x18(%rsp)
jmp 0x2ffcf
movsd 0x18(%rsp), %xmm0
movsd 0x13604b(%rip), %xmm1   # 0x166028
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, 0xe4(%rsp)
movl 0x118(%rsp), %esi
incl %esi
movl 0x114(%rsp), %edx
incl %edx
leaq 0x188(%rsp), %rdi
callq 0x1a060
movsd %xmm0, 0x10(%rsp)
jmp 0x30014
movsd 0x10(%rsp), %xmm0
movsd 0x136006(%rip), %xmm1   # 0x166028
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, 0xe0(%rsp)
movl $0x6, 0xdc(%rsp)
cmpq $0x0, 0x108(%rsp)
jne 0x300c5
cmpq $0x0, 0xf8(%rsp)
je 0x300c0
cmpq $0x0, 0xf0(%rsp)
je 0x300c0
cmpq $0x0, 0x100(%rsp)
je 0x300c0
movl 0xe8(%rsp), %eax
orl 0xe0(%rsp), %eax
orl 0xe4(%rsp), %eax
andl 0xdc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
je 0x300be
movq 0x280(%rsp), %rdi
movq 0xf8(%rsp), %rsi
movq 0xf0(%rsp), %rdx
movq 0x100(%rsp), %rcx
movq (%rdi), %rax
movq 0x48(%rax), %rax
xorl %r8d, %r8d
callq *%rax
jmp 0x300bc
jmp 0x300be
jmp 0x300c0
jmp 0x3030f
cmpq $0x0, 0xf8(%rsp)
jne 0x3014d
cmpq $0x0, 0x108(%rsp)
je 0x30148
cmpq $0x0, 0xf0(%rsp)
je 0x30148
cmpq $0x0, 0x100(%rsp)
je 0x30148
movl 0xec(%rsp), %eax
orl 0xe0(%rsp), %eax
orl 0xe4(%rsp), %eax
andl 0xdc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
je 0x30146
movq 0x280(%rsp), %rdi
movq 0x108(%rsp), %rsi
movq 0xf0(%rsp), %rdx
movq 0x100(%rsp), %rcx
movq (%rdi), %rax
movq 0x48(%rax), %rax
xorl %r8d, %r8d
callq *%rax
jmp 0x30144
jmp 0x30146
jmp 0x30148
jmp 0x3030d
cmpq $0x0, 0x100(%rsp)
jne 0x301d5
cmpq $0x0, 0x108(%rsp)
je 0x301d0
cmpq $0x0, 0xf8(%rsp)
je 0x301d0
cmpq $0x0, 0xf0(%rsp)
je 0x301d0
movl 0xec(%rsp), %eax
orl 0xe8(%rsp), %eax
orl 0xe0(%rsp), %eax
andl 0xdc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
je 0x301ce
movq 0x280(%rsp), %rdi
movq 0x108(%rsp), %rsi
movq 0xf8(%rsp), %rdx
movq 0xf0(%rsp), %rcx
movq (%rdi), %rax
movq 0x48(%rax), %rax
xorl %r8d, %r8d
callq *%rax
jmp 0x301cc
jmp 0x301ce
jmp 0x301d0
jmp 0x3030b
cmpq $0x0, 0xf0(%rsp)
jne 0x3025d
cmpq $0x0, 0x108(%rsp)
je 0x30258
cmpq $0x0, 0xf8(%rsp)
je 0x30258
cmpq $0x0, 0x100(%rsp)
je 0x30258
movl 0xec(%rsp), %eax
orl 0xe8(%rsp), %eax
orl 0xe4(%rsp), %eax
andl 0xdc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
je 0x30256
movq 0x280(%rsp), %rdi
movq 0x108(%rsp), %rsi
movq 0xf8(%rsp), %rdx
movq 0x100(%rsp), %rcx
movq (%rdi), %rax
movq 0x48(%rax), %rax
xorl %r8d, %r8d
callq *%rax
jmp 0x30254
jmp 0x30256
jmp 0x30258
jmp 0x30309
movl 0xec(%rsp), %eax
orl 0xe8(%rsp), %eax
orl 0xe0(%rsp), %eax
andl 0xdc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
je 0x302b2
movq 0x280(%rsp), %rdi
movq 0x108(%rsp), %rsi
movq 0xf8(%rsp), %rdx
movq 0xf0(%rsp), %rcx
movq (%rdi), %rax
movq 0x48(%rax), %rax
xorl %r8d, %r8d
callq *%rax
jmp 0x302b0
jmp 0x302b2
movl 0xec(%rsp), %eax
orl 0xe0(%rsp), %eax
orl 0xe4(%rsp), %eax
andl 0xdc(%rsp), %eax
cmpl 0xdc(%rsp), %eax
je 0x30307
movq 0x280(%rsp), %rdi
movq 0x108(%rsp), %rsi
movq 0xf0(%rsp), %rdx
movq 0x100(%rsp), %rcx
movq (%rdi), %rax
movq 0x48(%rax), %rax
xorl %r8d, %r8d
callq *%rax
jmp 0x30305
jmp 0x30307
jmp 0x30309
jmp 0x3030b
jmp 0x3030d
jmp 0x3030f
jmp 0x30311
movl 0x114(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x114(%rsp)
jmp 0x2fd8c
jmp 0x30329
movl 0x118(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x118(%rsp)
jmp 0x2fd4e
movq 0x260(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x3035c
movq 0x8(%rsp), %rdi
callq 0x12920
movq 0xd0(%rsp), %rdi
movq (%rdi), %rax
movq 0x148(%rax), %rax
callq *%rax
jmp 0x30372
movl $0x1, 0x294(%rsp)
movl $0x1, 0x178(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xb3390
movl 0x294(%rsp), %eax
addq $0x298, %rsp            # imm = 0x298
retq
movq 0x180(%rsp), %rdi
callq 0x12c20
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)