// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Grid.cpp
// Function: gaps::R3Grid::ReadGrid(_IO_FILE*)
int R3Grid::
ReadGrid(FILE *fp)
{
  // Check file
  if (!fp) fp = stdin;

  // Read grid resolution from file
  int res[3];
  if (fread(res, sizeof(int), 3, fp) != 3) {
    RNFail("Unable to read resolution from file");
    return 0;
  }

  // Re-allocate grid values
  int new_size = res[0] * res[1] * res[2];
  if (!grid_values || (new_size > grid_size)) { 
    if (grid_values) delete [] grid_values;
    grid_values = new RNScalar [ new_size ];
    assert(grid_values);
  }

  // Update grid resolution variables
  grid_resolution[0] = res[0];
  grid_resolution[1] = res[1];
  grid_resolution[2] = res[2];
  grid_row_size = grid_resolution[0];
  grid_sheet_size = grid_row_size * grid_resolution[1];
  grid_size = grid_sheet_size * grid_resolution[2];
  if (grid_size <= 0) {
    RNFail("Invalid grid size (%d) in file", grid_size);
    return 0;
  }

  // Read world_to_grid transformation to file
  RNScalar *m = (RNScalar *) &(world_to_grid_transform.Matrix()[0][0]);
  for (int i = 0; i < 16; i++) {
    float value;
    if (fread(&value, sizeof(float), 1, fp) != 1) {
      RNFail("Unable to read transformation matrix value to file");
      return 0;
    }
    else {
      *(m++) = (RNScalar) value;
    }
  }

  // Read grid values
  RNScalar *grid_valuesp = grid_values;
  for (int i = 0; i < grid_size; i++) {
    float value;
    if (fread(&value, sizeof(float), 1, fp) != 1) {
      RNFail("Unable to read grid value %d of %d from file", i, grid_size);
      return 0;
    }
    else {
      *(grid_valuesp++) = (RNScalar) value;
    }
  }

  // Update transformation variables
  world_to_grid_scale_factor = world_to_grid_transform.ScaleFactor();
  grid_to_world_scale_factor = (world_to_grid_scale_factor != 0) ? 1 / world_to_grid_scale_factor : 1.0;
  grid_to_world_transform = world_to_grid_transform.Inverse();

  // Return number of grid values read
  return grid_size;
}

// Assembly:
subq $0x188, %rsp            # imm = 0x188
movq %rdi, 0x178(%rsp)
movq %rsi, 0x170(%rsp)
movq 0x178(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x170(%rsp)
jne 0x66f01
movq 0x1080c2(%rip), %rax    # 0x16efb8
movq (%rax), %rax
movq %rax, 0x170(%rsp)
leaq 0x164(%rsp), %rdi
movq 0x170(%rsp), %rcx
movl $0x4, %esi
movl $0x3, %edx
callq 0xf780
cmpq $0x3, %rax
je 0x66f44
leaq 0xcd428(%rip), %rdi     # 0x134355
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x184(%rsp)
jmp 0x672da
movq 0x18(%rsp), %rax
movl 0x164(%rsp), %ecx
imull 0x168(%rsp), %ecx
imull 0x16c(%rsp), %ecx
movl %ecx, 0x160(%rsp)
cmpq $0x0, 0x230(%rax)
je 0x66f85
movq 0x18(%rsp), %rcx
movl 0x160(%rsp), %eax
cmpl 0x24c(%rcx), %eax
jle 0x66fef
movq 0x18(%rsp), %rax
cmpq $0x0, 0x230(%rax)
je 0x66fb7
movq 0x18(%rsp), %rax
movq 0x230(%rax), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x66fb5
movq 0x10(%rsp), %rdi
callq 0xf670
jmp 0x66fb7
movslq 0x160(%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 0x18(%rsp), %rax
movq %rcx, 0x230(%rax)
movq 0x18(%rsp), %rax
movl 0x164(%rsp), %ecx
movl %ecx, 0x238(%rax)
movl 0x168(%rsp), %ecx
movl %ecx, 0x23c(%rax)
movl 0x16c(%rsp), %ecx
movl %ecx, 0x240(%rax)
movl 0x238(%rax), %ecx
movl %ecx, 0x244(%rax)
movl 0x244(%rax), %ecx
imull 0x23c(%rax), %ecx
movl %ecx, 0x248(%rax)
movl 0x248(%rax), %ecx
imull 0x240(%rax), %ecx
movl %ecx, 0x24c(%rax)
cmpl $0x0, 0x24c(%rax)
jg 0x6707f
movq 0x18(%rsp), %rax
movl 0x24c(%rax), %esi
leaq 0xcd311(%rip), %rdi     # 0x134379
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x184(%rsp)
jmp 0x672da
movq 0x18(%rsp), %rdi
addq $0x110, %rdi            # imm = 0x110
callq 0x4e2a0
movq %rax, %rdi
xorl %esi, %esi
callq 0x4e280
movq %rax, 0x158(%rsp)
movl $0x0, 0x154(%rsp)
cmpl $0x10, 0x154(%rsp)
jge 0x6713e
movq 0x170(%rsp), %rcx
leaq 0x150(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0xf780
cmpq $0x1, %rax
je 0x670fe
leaq 0xcd2b1(%rip), %rdi     # 0x134398
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x184(%rsp)
jmp 0x672da
movss 0x150(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movq 0x158(%rsp), %rax
movq %rax, %rcx
addq $0x8, %rcx
movq %rcx, 0x158(%rsp)
movsd %xmm0, (%rax)
jmp 0x67128
movl 0x154(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x154(%rsp)
jmp 0x670ad
movq 0x18(%rsp), %rax
movq 0x230(%rax), %rax
movq %rax, 0x148(%rsp)
movl $0x0, 0x144(%rsp)
movq 0x18(%rsp), %rcx
movl 0x144(%rsp), %eax
cmpl 0x24c(%rcx), %eax
jge 0x6720a
movq 0x170(%rsp), %rcx
leaq 0x140(%rsp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0xf780
cmpq $0x1, %rax
je 0x671ca
movq 0x18(%rsp), %rax
movl 0x144(%rsp), %esi
movl 0x24c(%rax), %edx
leaq 0xcd218(%rip), %rdi     # 0x1343cb
movb $0x0, %al
callq 0xd4f30
movl $0x0, 0x184(%rsp)
jmp 0x672da
movss 0x140(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movq 0x148(%rsp), %rax
movq %rax, %rcx
addq $0x8, %rcx
movq %rcx, 0x148(%rsp)
movsd %xmm0, (%rax)
jmp 0x671f4
movl 0x144(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x144(%rsp)
jmp 0x6715d
movq 0x18(%rsp), %rdi
addq $0x110, %rdi            # imm = 0x110
callq 0x4d5d0
movq 0x18(%rsp), %rax
movsd %xmm0, 0x220(%rax)
movsd 0x220(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x6723d
jp 0x6723d
jmp 0x6725a
movq 0x18(%rsp), %rax
movsd 0xcbdbe(%rip), %xmm0    # 0x133008
divsd 0x220(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
jmp 0x6726a
movsd 0xcbda6(%rip), %xmm0    # 0x133008
movsd %xmm0, 0x8(%rsp)
jmp 0x6726a
movq 0x18(%rsp), %rsi
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x228(%rsi)
addq $0x110, %rsi            # imm = 0x110
leaq 0x30(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x6be40
movq 0x18(%rsp), %rdi
movq (%rsp), %rsi
callq 0x392c0
jmp 0x672a2
leaq 0x30(%rsp), %rdi
callq 0x4d430
movq 0x18(%rsp), %rax
movl 0x24c(%rax), %eax
movl %eax, 0x184(%rsp)
jmp 0x672da
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x4d430
jmp 0x672e9
movl 0x184(%rsp), %eax
addq $0x188, %rsp            # imm = 0x188
retq
movq 0x28(%rsp), %rdi
callq 0xf890
nopw %cs:(%rax,%rax)