// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3MeshPropertySet.cpp
// Function: gaps::R3MeshPropertySet::ReadToronto(char const*)
int R3MeshPropertySet::
ReadToronto(const char *filename)
{
  // Get base property name
  char *name = NULL;
  char buffer[512];
  strcpy(buffer, filename);
  name = strrchr(buffer, '/');
  if (name) name++; 
  else name = buffer;
  char *end = strrchr(name, '.');
  if (end) *end = '\0';

  // Open file
  FILE *fp = fopen(filename, "r");
  if (!fp) {
    RNFail("Unable to open toronto file: %s\n", filename);
    return 0;
  }

  // Read header
  int nprops, nfaces, dummy;
  if (fscanf(fp, "%d%d%d\n", &nprops, &nfaces, &dummy) != (unsigned int) 3) {
    RNFail("Unable to read toronto file: %s\n", filename);
    return 0;
  }

  // Check header
  if ((nprops == 0) || (nfaces == 0) || (nfaces != mesh->NFaces())) {
    RNFail("Invalid header in toronto file: %s\n", filename);
    return 0;
  }

  // Allocate memory for face values
  double *face_values = new double [ nprops * nfaces ];
  if (!face_values) {
    RNFail("Unable to allocate memory for toronto file: %s\n", filename);
    return 0;
  }

  // Read face values
  for (int j = 0; j < nfaces; j++) {
    for (int i = 0; i < nprops; i++) {
      if (fscanf(fp, "%lf", &face_values[i*nfaces+j]) != (unsigned int) 1) {
        RNFail("Unable to read value %d for face %d in %s\n", i, j, filename);
        return 0;
      }
    }
  }

  // Create properties
  for (int i = 0; i < nprops; i++) {
    // Allocate property
    char property_name[1024];
    sprintf(property_name, "%s%d", name, i);
    R3MeshProperty *property = new R3MeshProperty(mesh, property_name);

    // Compute property values by interpolation from attached faces
    for (int j = 0; j < mesh->NVertices(); j++) {
      R3MeshVertex *vertex = mesh->Vertex(j);
      RNScalar total_value = 0;
      RNScalar total_weight = 0;
      for (int k = 0; k < mesh->VertexValence(vertex); k++) {
        R3MeshEdge *edge = mesh->EdgeOnVertex(vertex, k);
        R3MeshFace *face = mesh->FaceOnVertex(vertex, edge);
        if (!face) continue;
        int face_index = mesh->FaceID(face);
        RNScalar value = face_values[i*nfaces + face_index];
        RNScalar weight = mesh->FaceArea(face);
        total_value += weight * value;
        total_weight += weight;
      }
      if (total_weight > 0) {
        property->SetVertexValue(j, total_value / total_weight);
      }
    }

    // Insert property
    Insert(property);
  }

  // Close file
  fclose(fp);

  // Delete memory for face values
  delete [] face_values;

  // Return success
  return 1;
}

// Assembly:
subq $0x708, %rsp            # imm = 0x708
movq %rdi, 0x6f8(%rsp)
movq %rsi, 0x6f0(%rsp)
movq 0x6f8(%rsp), %rax
movq %rax, 0x38(%rsp)
movq $0x0, 0x6e8(%rsp)
leaq 0x4e0(%rsp), %rdi
movq 0x6f0(%rsp), %rsi
callq 0x228f0
leaq 0x4e0(%rsp), %rdi
movl $0x2f, %esi
callq 0x22b00
movq %rax, 0x6e8(%rsp)
cmpq $0x0, 0x6e8(%rsp)
je 0x6ace0
movq 0x6e8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x6e8(%rsp)
jmp 0x6acf0
leaq 0x4e0(%rsp), %rax
movq %rax, 0x6e8(%rsp)
movq 0x6e8(%rsp), %rdi
movl $0x2e, %esi
callq 0x22b00
movq %rax, 0x4d8(%rsp)
cmpq $0x0, 0x4d8(%rsp)
je 0x6ad20
movq 0x4d8(%rsp), %rax
movb $0x0, (%rax)
movq 0x6f0(%rsp), %rdi
leaq 0x132bb4(%rip), %rsi    # 0x19d8e3
callq 0x22bf0
movq %rax, 0x4d0(%rsp)
cmpq $0x0, 0x4d0(%rsp)
jne 0x6ad6d
movq 0x6f0(%rsp), %rsi
leaq 0x12d442(%rip), %rdi    # 0x198198
movb $0x0, %al
callq 0xfbc30
movl $0x0, 0x704(%rsp)
jmp 0x6b242
movq 0x4d0(%rsp), %rdi
leaq 0x12d43d(%rip), %rsi    # 0x1981b9
leaq 0x4cc(%rsp), %rdx
leaq 0x4c8(%rsp), %rcx
leaq 0x4c4(%rsp), %r8
movb $0x0, %al
callq 0x23350
cmpl $0x3, %eax
je 0x6adc6
movq 0x6f0(%rsp), %rsi
leaq 0x12d412(%rip), %rdi    # 0x1981c1
movb $0x0, %al
callq 0xfbc30
movl $0x0, 0x704(%rsp)
jmp 0x6b242
cmpl $0x0, 0x4cc(%rsp)
je 0x6adfc
cmpl $0x0, 0x4c8(%rsp)
je 0x6adfc
movq 0x38(%rsp), %rax
movl 0x4c8(%rsp), %ecx
movl %ecx, 0x34(%rsp)
movq (%rax), %rdi
callq 0x2a9d0
movl %eax, %ecx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
je 0x6ae22
movq 0x6f0(%rsp), %rsi
leaq 0x12d3d7(%rip), %rdi    # 0x1981e2
movb $0x0, %al
callq 0xfbc30
movl $0x0, 0x704(%rsp)
jmp 0x6b242
movl 0x4cc(%rsp), %eax
imull 0x4c8(%rsp), %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x22040
movq %rax, 0x4b8(%rsp)
cmpq $0x0, 0x4b8(%rsp)
jne 0x6ae8d
movq 0x6f0(%rsp), %rsi
leaq 0x12d390(%rip), %rdi    # 0x198206
movb $0x0, %al
callq 0xfbc30
movl $0x0, 0x704(%rsp)
jmp 0x6b242
movl $0x0, 0x4b4(%rsp)
movl 0x4b4(%rsp), %eax
cmpl 0x4c8(%rsp), %eax
jge 0x6af71
movl $0x0, 0x4b0(%rsp)
movl 0x4b0(%rsp), %eax
cmpl 0x4cc(%rsp), %eax
jge 0x6af59
movq 0x4d0(%rsp), %rdi
movq 0x4b8(%rsp), %rdx
movl 0x4b0(%rsp), %eax
imull 0x4c8(%rsp), %eax
addl 0x4b4(%rsp), %eax
cltq
shlq $0x3, %rax
addq %rax, %rdx
leaq 0x12dab4(%rip), %rsi    # 0x1989b5
movb $0x0, %al
callq 0x23350
cmpl $0x1, %eax
je 0x6af41
movl 0x4b0(%rsp), %esi
movl 0x4b4(%rsp), %edx
movq 0x6f0(%rsp), %rcx
leaq 0x12d30c(%rip), %rdi    # 0x198236
movb $0x0, %al
callq 0xfbc30
movl $0x0, 0x704(%rsp)
jmp 0x6b242
jmp 0x6af43
movl 0x4b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4b0(%rsp)
jmp 0x6aeb7
jmp 0x6af5b
movl 0x4b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4b4(%rsp)
jmp 0x6ae98
movl $0x0, 0x4ac(%rsp)
movl 0x4ac(%rsp), %eax
cmpl 0x4cc(%rsp), %eax
jge 0x6b20d
movq 0x6e8(%rsp), %rdx
movl 0x4ac(%rsp), %ecx
leaq 0x12c035(%rip), %rsi    # 0x196fdb
xorl %eax, %eax
movl %eax, 0x24(%rsp)
leaq 0xa0(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x22150
movl $0x448, %edi            # imm = 0x448
callq 0x229d0
movq 0x38(%rsp), %rcx
movq 0x18(%rsp), %rdx
movq %rax, %rdi
movl 0x24(%rsp), %eax
movq %rdi, %rsi
movq %rsi, 0x28(%rsp)
movq (%rcx), %rsi
movl %eax, %ecx
callq 0x6c2b0
jmp 0x6afed
movq 0x28(%rsp), %rax
movq %rax, 0x98(%rsp)
movl $0x0, 0x88(%rsp)
movq 0x38(%rsp), %rax
movl 0x88(%rsp), %ecx
movl %ecx, 0x14(%rsp)
movq (%rax), %rdi
callq 0x2abd0
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
jge 0x6b1e5
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movl 0x88(%rsp), %esi
callq 0x2abf0
movq %rax, 0x80(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x78(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x70(%rsp)
movl $0x0, 0x6c(%rsp)
movq 0x38(%rsp), %rax
movl 0x6c(%rsp), %ecx
movl %ecx, 0x10(%rsp)
movq (%rax), %rdi
movq 0x80(%rsp), %rsi
callq 0x6c0d0
movl %eax, %ecx
movl 0x10(%rsp), %eax
cmpl %ecx, %eax
jge 0x6b19e
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movq 0x80(%rsp), %rsi
movl 0x6c(%rsp), %edx
callq 0x6c100
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x60(%rsp)
movq (%rax), %rdi
movq 0x80(%rsp), %rsi
movq 0x60(%rsp), %rdx
xorl %ecx, %ecx
callq 0x6c130
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x6b103
jmp 0x6b18e
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x90(%rsp)
movl %eax, 0x8c(%rsp)
movl $0x448, %esi            # imm = 0x448
callq 0x229f0
jmp 0x6b251
movq 0x38(%rsp), %rax
movq (%rax), %rdi
movq 0x58(%rsp), %rsi
callq 0x6c170
movl %eax, %ecx
movq 0x38(%rsp), %rax
movl %ecx, 0x54(%rsp)
movq 0x4b8(%rsp), %rcx
movl 0x4ac(%rsp), %edx
imull 0x4c8(%rsp), %edx
addl 0x54(%rsp), %edx
movslq %edx, %rdx
movsd (%rcx,%rdx,8), %xmm0
movsd %xmm0, 0x48(%rsp)
movq (%rax), %rdi
movq 0x58(%rsp), %rsi
callq 0x6c190
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm0
movsd 0x48(%rsp), %xmm2
movsd 0x78(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x40(%rsp), %xmm0
addsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x6b061
movsd 0x70(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x6b1cd
movq 0x98(%rsp), %rdi
movl 0x88(%rsp), %esi
movsd 0x78(%rsp), %xmm0
divsd 0x70(%rsp), %xmm0
callq 0x6f210
jmp 0x6b1cf
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x6b005
movq 0x38(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x69220
movl 0x4ac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4ac(%rsp)
jmp 0x6af7c
movq 0x4d0(%rsp), %rdi
callq 0x229c0
movq 0x4b8(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x6b237
movq 0x8(%rsp), %rdi
callq 0x22d80
movl $0x1, 0x704(%rsp)
movl 0x704(%rsp), %eax
addq $0x708, %rsp            # imm = 0x708
retq
movq 0x90(%rsp), %rdi
callq 0x23270
nop