// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelScene.cpp
// Function: gaps::R3SurfelScene::WriteTianqiangFile(char const*)
int R3SurfelScene::
WriteTianqiangFile(const char *filename) 
{
  // Open file
  FILE *fp = fopen(filename, "w");
  if (!fp) {
    RNFail("Unable to open file %s\n", filename);
    return 0;
  }
  
  // Get scene name
  char scene_name_buffer[2048];
  strncpy(scene_name_buffer, filename, 2047);
  char *scene_name = strrchr(scene_name_buffer, '.');
  if (scene_name) *scene_name = '\0';
  scene_name = strrchr(scene_name_buffer, '/');
  if (scene_name) scene_name++;
  else scene_name = scene_name_buffer;

  // Allocate node and leaf index
  int node_count = 0;
  int leaf_count = 0;
  int *node_index = new int [ NObjects() ];
  int *leaf_index = new int [ NObjects() ];
  for (int i = 0; i < NObjects(); i++) node_index[i] = -1;
  for (int i = 0; i < NObjects(); i++) leaf_index[i] = -1;

  // Compute node and leaf index
  RNArray<R3SurfelObject *> index_stack;
  index_stack.Insert(RootObject());
  while (!index_stack.IsEmpty()) {
    // Pop object off stack
    R3SurfelObject *object = index_stack.Tail();
    index_stack.RemoveTail();

    // Push children on stack
    for (int j = 0; j < object->NParts(); j++) {
      index_stack.Insert(object->Part(j));
    }

    // Check object
    if (object->NParts() == 0) {
      if (object->Parent() == RootObject()) {
        if (!object->GroundTruthLabel() && !object->HumanLabel()) {
          continue;
        }
      }
    }

    // Add object to node index
    node_index[object->SceneIndex()] = node_count++;

    // Add object to leaf index
    if (object->NParts() == 0) {
      leaf_index[object->SceneIndex()] = leaf_count++;
    }
  }

  // Create off directory
  char mkdir_command[4096];
  sprintf(mkdir_command, "mkdir -p %s_off_files", scene_name);
  system(mkdir_command);

  // Write off files
  for (int i = 0; i < NObjects(); i++) {
    R3SurfelObject *object = Object(i);
    if (leaf_index[i] < 0) continue;
    char off_filename[4096];
    sprintf(off_filename, "%s_off_files/%d.off", scene_name, leaf_index[i]);
    if (!WriteOffFile(object, off_filename)) return 0;
  }

  // Write header
  fprintf(fp, "root 0\n");
  fprintf(fp, "scene_name %s\n", scene_name);
  
  // Write objects
  RNArray<R3SurfelObject *> object_stack;
  object_stack.Insert(RootObject());
  while (!object_stack.IsEmpty()) {
    // Pop object off stack
    R3SurfelObject *object = object_stack.Tail();
    object_stack.RemoveTail();

    // Push children on stack
    for (int j = 0; j < object->NParts(); j++) {
      object_stack.Insert(object->Part(j));
    }

    // Check object
    if (node_index[object->SceneIndex()] < 0) continue;

    // Write object header
    fprintf(fp, "newModel %d\n", node_index[object->SceneIndex()]);

    // Write parent 
    R3SurfelObject *parent = object->Parent();
    int parent_index = (parent) ? node_index[parent->SceneIndex()] : -1;
    fprintf(fp, "parent %d\n", parent_index);

    // Write children
    fprintf(fp, "children ");
    for (int j = 0; j < object->NParts(); j++) {
      R3SurfelObject *part = object->Part(j);
      if (node_index[part->SceneIndex()] < 0) continue;
      fprintf(fp, "%d ", node_index[part->SceneIndex()]);
    }
    fprintf(fp, "\n");

    // Write leaf group
    fprintf(fp, "leaf_group");
    RNArray<R3SurfelObject *> part_stack;
    part_stack.Insert(object);
    while (!part_stack.IsEmpty()) {
      R3SurfelObject *part = part_stack.Tail();
      part_stack.RemoveTail();
      for (int j = 0; j < part->NParts(); j++) part_stack.Insert(part->Part(j));
      int g = leaf_index[part->SceneIndex()];
      if (g != -1) fprintf(fp, " %d", g);
    }
    fprintf(fp, "\n");
    
    // Write label
    R3SurfelLabel *label = object->GroundTruthLabel();
    if (!label) label = object->HumanLabel();
    if (!label && (object == RootObject())) label = RootLabel();
    if (label) fprintf(fp, "label %d %s\n", label->SceneIndex(), label->Name());;

    // Write feature vector
    // const R3SurfelFeatureVector& vector = object->FeatureVector();
    // fprintf(fp, "feature_vector ");
    // for (int j = 0; j < vector.NValues(); j++) 
    //   fprintf(fp, "%12.6f ", vector.Value(j));
    // fprintf(fp, "\n");
  }
  
  // Delete temporary data
  delete [] node_index;
  delete [] leaf_index;

  // Close file
  fclose(fp);

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x29e8, %rsp           # imm = 0x29E8
movq %rsi, %r14
movq %rdi, %r13
leaq 0xaef4a(%rip), %rsi     # 0xcf284
movq %r14, %rdi
callq 0x135f0
movq %rax, 0x8(%rsp)
testq %rax, %rax
je 0x2068c
leaq 0x11e0(%rsp), %rbx
movl $0x7ff, %edx            # imm = 0x7FF
movq %rbx, %rdi
movq %r14, %rsi
callq 0x13290
pushq $0x2e
popq %rsi
movq %rbx, %rdi
callq 0x13580
testq %rax, %rax
je 0x2037b
movb $0x0, (%rax)
leaq 0x11e0(%rsp), %rbx
pushq $0x2f
popq %rsi
movq %rbx, %rdi
callq 0x13580
movq %rax, %r14
incq %rax
movq %rax, 0x18(%rsp)
movslq 0x1c(%r13), %r12
leaq (,%r12,4), %rax
testq %r12, %r12
pushq $-0x1
popq %r15
cmovnsq %rax, %r15
movq %r15, %rdi
callq 0x13030
movq %rax, 0x10(%rsp)
movq %r15, %rdi
callq 0x13030
movq %rax, 0x20(%rsp)
xorl %ecx, %ecx
testl %r12d, %r12d
movl $0x0, %eax
cmovgl %r12d, %eax
movq 0x10(%rsp), %rdx
cmpq %rcx, %rax
je 0x203eb
orl $-0x1, (%rdx,%rcx,4)
incq %rcx
jmp 0x203dd
xorl %ecx, %ecx
movq 0x20(%rsp), %rdx
cmpq %rcx, %rax
je 0x20400
orl $-0x1, (%rdx,%rcx,4)
incq %rcx
jmp 0x203f2
testq %r14, %r14
movq 0x18(%rsp), %rax
cmoveq %rbx, %rax
movq %rax, 0x18(%rsp)
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
callq 0x9a7ae
movq 0x10(%r13), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x1784c
xorl %r15d, %r15d
leaq 0x30(%rsp), %rbx
xorl %ebp, %ebp
movslq 0x3c(%rsp), %rax
testq %rax, %rax
je 0x204cd
movq 0x30(%rsp), %rcx
movq -0x8(%rcx,%rax,8), %r14
movq %rbx, %rdi
callq 0x17820
xorl %r12d, %r12d
movslq 0x2c(%r14), %rax
cmpq %rax, %r12
jge 0x20478
movq 0x20(%r14), %rax
movq (%rax,%r12,8), %rsi
movq %rbx, %rdi
callq 0x1784c
incq %r12
jmp 0x2045a
testl %eax, %eax
jne 0x204a3
movq 0x18(%r14), %rax
movq 0x10(%r13), %rcx
cmpq (%rcx), %rax
jne 0x204a3
movq %r14, %rdi
callq 0x16d5a
testq %rax, %rax
jne 0x204a3
movq %r14, %rdi
callq 0x16d70
testq %rax, %rax
je 0x20437
movslq 0x10(%r14), %rax
movq 0x10(%rsp), %rcx
movl %ebp, (%rcx,%rax,4)
incl %ebp
cmpl $0x0, 0x2c(%r14)
jne 0x20437
movq 0x20(%rsp), %rcx
movl %r15d, (%rcx,%rax,4)
incl %r15d
jmp 0x20437
leaq 0xa84c6(%rip), %rsi     # 0xc899a
leaq 0x19e0(%rsp), %rbx
movq %rbx, %rdi
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0x130e0
movq %rbx, %rdi
callq 0x13430
leaq 0x1e0(%rsp), %r15
leaq 0xa8(%rsp), %r14
xorl %edx, %edx
movq %r13, 0x28(%rsp)
movslq 0x1c(%r13), %rax
cmpq %rax, %rdx
jge 0x206ab
movq 0x20(%rsp), %rax
movl (%rax,%rdx,4), %ecx
testl %ecx, %ecx
js 0x20684
movq 0x10(%r13), %rax
movq %rdx, 0x40(%rsp)
movq (%rax,%rdx,8), %rbx
movq %r15, %rdi
leaq 0xa8472(%rip), %rsi     # 0xc89b0
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0x130e0
xorpd %xmm0, %xmm0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x16b9c
movq %rax, %rbx
testq %rax, %rax
je 0x206a4
movq %r14, %rdi
callq 0x4dc0c
xorl %r15d, %r15d
xorl %r13d, %r13d
movslq 0x10(%rbx), %rax
cmpq %rax, %r13
jge 0x20650
movq 0x8(%rbx), %rsi
addq %r15, %rsi
leaq 0x90(%rsp), %r12
movq %r12, %rdi
callq 0x16310
leaq 0x78(%rsp), %rdi
movq %r12, %rsi
callq 0x781cc
movsd 0x78(%rsp), %xmm0
addsd 0xa7dd7(%rip), %xmm0    # 0xc8388
movsd %xmm0, 0x78(%rsp)
leaq 0x60(%rsp), %rdi
movq %r12, %rsi
callq 0x781cc
movsd 0x60(%rsp), %xmm0
movsd 0xa7dbe(%rip), %xmm1    # 0xc8390
addsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
leaq 0x48(%rsp), %rdi
movq %r12, %rsi
callq 0x781cc
movsd 0x50(%rsp), %xmm0
addsd 0xa7d99(%rip), %xmm0    # 0xc8390
movsd %xmm0, 0x50(%rsp)
movq %r14, %rdi
leaq 0x78(%rsp), %rsi
xorl %edx, %edx
callq 0x5098c
movq %rax, %rbp
movq %r14, %rdi
leaq 0x60(%rsp), %rsi
xorl %edx, %edx
callq 0x5098c
movq %rax, %r12
movq %r14, %rdi
leaq 0x48(%rsp), %rsi
xorl %edx, %edx
callq 0x5098c
movq %r14, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x50cc4
incq %r13
addq $0x10, %r15
jmp 0x20572
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
movq %r14, %rdi
leaq 0x1e0(%rsp), %r15
movq %r15, %rsi
callq 0x5cb38
movl %eax, %ebx
movq %r14, %rdi
callq 0x4e0f4
testl %ebx, %ebx
movq 0x28(%rsp), %r13
je 0x206a4
movq 0x40(%rsp), %rdx
incq %rdx
jmp 0x2050a
leaq 0xa7e3f(%rip), %rdi     # 0xc84d2
xorl %ebx, %ebx
movq %r14, %rsi
xorl %eax, %eax
callq 0x9ce26
jmp 0x2093f
xorl %ebx, %ebx
jmp 0x20935
leaq 0xa8312(%rip), %rdi     # 0xc89c4
pushq $0x7
popq %rsi
pushq $0x1
popq %rdx
movq 0x8(%rsp), %rbx
movq %rbx, %rcx
callq 0x139e0
leaq 0xa8300(%rip), %rsi     # 0xc89cc
movq %rbx, %rdi
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0x13780
leaq 0x1e0(%rsp), %rdi
callq 0x9a7ae
movq 0x10(%r13), %rax
movq (%rax), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0x1784c
leaq 0x1e0(%rsp), %r13
pushq $-0x1
popq %rbx
leaq 0xa8(%rsp), %r14
movslq 0x1ec(%rsp), %rax
testq %rax, %rax
je 0x20907
movq 0x1e0(%rsp), %rcx
movq -0x8(%rcx,%rax,8), %rbp
movq %r13, %rdi
callq 0x17820
xorl %r15d, %r15d
movslq 0x2c(%rbp), %rax
cmpq %rax, %r15
jge 0x20756
movq 0x20(%rbp), %rax
movq (%rax,%r15,8), %rsi
movq %r13, %rdi
callq 0x1784c
incq %r15
jmp 0x20738
movslq 0x10(%rbp), %rax
movq 0x10(%rsp), %rcx
movl (%rcx,%rax,4), %edx
testl %edx, %edx
js 0x2070f
movq 0x8(%rsp), %rdi
leaq 0xa8269(%rip), %rsi     # 0xc89db
xorl %eax, %eax
callq 0x13780
movq 0x18(%rbp), %rax
movl %ebx, %edx
testq %rax, %rax
je 0x20790
movslq 0x10(%rax), %rax
movq 0x10(%rsp), %rcx
movl (%rcx,%rax,4), %edx
movq 0x8(%rsp), %r15
movq %r15, %rdi
leaq 0xa8249(%rip), %rsi     # 0xc89e8
xorl %eax, %eax
callq 0x13780
leaq 0xa8246(%rip), %rdi     # 0xc89f3
pushq $0x9
popq %rsi
pushq $0x1
popq %rdx
movq %r15, %rcx
callq 0x139e0
xorl %r15d, %r15d
movslq 0x2c(%rbp), %rax
cmpq %rax, %r15
jge 0x207f7
movq 0x20(%rbp), %rax
movq (%rax,%r15,8), %rax
movslq 0x10(%rax), %rax
movq 0x10(%rsp), %rcx
movl (%rcx,%rax,4), %edx
testl %edx, %edx
js 0x207f2
movq 0x8(%rsp), %rdi
leaq 0xa80b8(%rip), %rsi     # 0xc88a3
xorl %eax, %eax
callq 0x13780
incq %r15
jmp 0x207be
pushq $0xa
popq %rdi
movq 0x8(%rsp), %r15
movq %r15, %rsi
callq 0x13690
leaq 0xa81ef(%rip), %rdi     # 0xc89fd
pushq $0xa
popq %rsi
pushq $0x1
popq %rdx
movq %r15, %rcx
callq 0x139e0
movq %r14, %rdi
callq 0x9a7ae
movq %r14, %rdi
movq %rbp, %rsi
callq 0x1784c
movslq 0xb4(%rsp), %rax
testq %rax, %rax
je 0x20898
movq 0xa8(%rsp), %rcx
movq -0x8(%rcx,%rax,8), %r15
movq %r14, %rdi
callq 0x17820
xorl %r12d, %r12d
movslq 0x2c(%r15), %rax
cmpq %rax, %r12
jge 0x20872
movq 0x20(%r15), %rax
movq (%rax,%r12,8), %rsi
movq %r14, %rdi
callq 0x1784c
incq %r12
jmp 0x20854
movslq 0x10(%r15), %rax
movq 0x20(%rsp), %rcx
movl (%rcx,%rax,4), %edx
cmpl $-0x1, %edx
je 0x2082f
movq 0x8(%rsp), %rdi
leaq 0xb299a(%rip), %rsi     # 0xd3229
xorl %eax, %eax
callq 0x13780
jmp 0x2082f
pushq $0xa
popq %rdi
movq 0x8(%rsp), %rsi
callq 0x13690
movq %rbp, %rdi
callq 0x16d5a
testq %rax, %rax
jne 0x208bf
movq %rbp, %rdi
callq 0x16d70
testq %rax, %rax
je 0x208e6
movl 0x10(%rax), %edx
movq 0x60(%rax), %rcx
movq 0x8(%rsp), %rdi
leaq 0xa8136(%rip), %rsi     # 0xc8a08
xorl %eax, %eax
callq 0x13780
movq %r14, %rdi
callq 0x9a81c
jmp 0x2070f
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
cmpq (%rax), %rbp
jne 0x208d9
movq 0x28(%rsp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rax
testq %rax, %rax
jne 0x208bf
jmp 0x208d9
movq 0x10(%rsp), %rdi
callq 0x136a0
movq 0x20(%rsp), %rdi
callq 0x136a0
movq 0x8(%rsp), %rdi
callq 0x134e0
leaq 0x1e0(%rsp), %rdi
callq 0x9a81c
pushq $0x1
popq %rbx
leaq 0x30(%rsp), %rdi
callq 0x9a81c
movl %ebx, %eax
addq $0x29e8, %rsp           # imm = 0x29E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x20977
jmp 0x2098e
jmp 0x2098e
jmp 0x2098e
jmp 0x2097c
jmp 0x20977
jmp 0x20993
jmp 0x20993
jmp 0x20977
jmp 0x2098e
jmp 0x2098e
jmp 0x2097c
jmp 0x2097c
jmp 0x2097c
jmp 0x2097c
jmp 0x2097c
jmp 0x2097c
jmp 0x20993
movq %rax, %rbx
jmp 0x209a3
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x4e0f4
jmp 0x209b0
movq %rax, %rbx
jmp 0x209b0
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x9a81c
leaq 0x1e0(%rsp), %rdi
callq 0x9a81c
leaq 0x30(%rsp), %rdi
callq 0x9a81c
movq %rbx, %rdi
callq 0x138f0