// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/apps/sflprocess/sflprocess.cpp
// Function: TransformWithConfigurationFile(gaps::R3SurfelScene*, char const*, int)
static int
TransformWithConfigurationFile(R3SurfelScene *scene, const char *filename, RNBoolean invert = FALSE)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();
  int count = 0;
  
  // Get surfel tree
  R3SurfelTree *tree = scene->Tree();
  if (!tree) {
    RNFail("Scene has no surfel tree\n");
    return 0;
  }    

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

  // Parse file
  char buffer[4096];
  int line_number = 0;
  while (fgets(buffer, 4096, fp)) {
    char cmd[4096];
    line_number++;
    if (sscanf(buffer, "%s", cmd) != (unsigned int) 1) continue;
    if (cmd[0] == '#') continue;

    // Check cmd
    if (!strcmp(cmd, "scan") || !strcmp(cmd, "image") || !strcmp(cmd, "frame")) {
      // Parse image name and alignment transformation
      RNScalar m[16], depth_timestamp, color_timestamp;
      char depth_name[1024], color_name[1024];
      if (!strcmp(cmd, "frame")) {
        if (sscanf(buffer, "%s%s%lf%s%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", cmd, 
           depth_name, &depth_timestamp, color_name, &color_timestamp,
           &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7], 
           &m[8], &m[9], &m[10], &m[11], &m[12], &m[13], &m[14], &m[15]) != (unsigned int) 21) {
          RNFail("Error parsing line %d of %s\n", line_number, filename);
          return 0;
        }
      }
      else {
        if (sscanf(buffer, "%s%s%s%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", cmd, 
           depth_name, color_name,
           &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7], 
           &m[8], &m[9], &m[10], &m[11], &m[12], &m[13], &m[14], &m[15]) != (unsigned int) 19) {
          RNFail("Error parsing line %d of %s\n", line_number, filename);
          return 0;
        }
      }

      // Get transformation
      R3Affine transformation(R4Matrix(m), 0);
      if (invert) transformation.Invert();

      // Get image name
      char tmp[2048];
      strncpy(tmp, depth_name, 1048);
      char *image_name = strrchr(tmp, '/');
      if (!image_name) image_name = tmp;
      char *endp = strrchr(image_name, '.');
      if (endp) *endp = '\0';
      char node_name[4096];
      sprintf(node_name, "SCAN:%s", image_name);

      // Find node
      R3SurfelNode *node = tree->FindNodeByName(node_name);
      R3SurfelScan *scan = scene->FindScanByName(image_name);
      R3SurfelImage *image = scene->FindImageByName(image_name);
      
      // Transform image
      if (image) {
        R3CoordSystem pose = image->Pose();
        pose.Transform(transformation);
        image->SetPose(pose);
      }
      
      // Transform scan
      if (scan) {
        R3CoordSystem pose = scan->Pose();
        pose.Transform(transformation);
        scan->SetPose(pose);
      }
      
      // Transform node and all its decendents
      if (node) {
        RNArray<R3SurfelNode *> stack;
        stack.Insert(node);
        while (!stack.IsEmpty()) {
          R3SurfelNode *node = stack.Tail();
          stack.RemoveTail();
          node->Transform(transformation);
          for (int i = 0; i < node->NParts(); i++) {
            stack.InsertTail(node->Part(i));
          }
        }
      }

      // Update statistics
      count++;
    }
  }

  // Close configuration file
  fclose(fp);

  // Print statistics
  if (print_verbose) {
    printf("Tranformed nodes ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Nodes = %d\n", count);
    fflush(stdout);
  }

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4248, %rsp           # imm = 0x4248
movl %edx, 0x8(%rsp)
movq %rsi, %r14
movq %rdi, %r15
leaq 0xc0(%rsp), %rbx
movq %rbx, %rdi
callq 0xaf4d6
movq %rbx, %rdi
callq 0x1d806
movq 0x8(%r15), %rax
movq %rax, 0xa8(%rsp)
testq %rax, %rax
je 0x1d437
leaq 0xdcf64(%rip), %rsi     # 0xf9f13
movq %r14, %rdi
callq 0x15760
testq %rax, %rax
je 0x1d4a8
movq %rax, %r13
movq %r15, 0xa0(%rsp)
movq %r14, 0x90(%rsp)
leaq 0xa40(%rsp), %rbx
leaq 0x130(%rsp), %r15
leaq 0xd0(%rsp), %r14
movl $0x0, 0x4(%rsp)
xorl %ebp, %ebp
movq %rax, 0x98(%rsp)
movq %rbx, %rdi
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdx
callq 0x159f0
testq %rax, %rax
je 0x1d44c
incl 0x4(%rsp)
movq %rbx, %rdi
leaq 0xd81d1(%rip), %rsi     # 0xf51f5
leaq 0x1a40(%rsp), %rdx
xorl %eax, %eax
callq 0x155f0
cmpl $0x1, %eax
jne 0x1d42a
cmpb $0x23, 0x1a40(%rsp)
je 0x1d42a
leaq 0x1a40(%rsp), %rbx
movq %rbx, %rdi
leaq 0xdc0be(%rip), %rsi     # 0xf911a
pushq $0x5
popq %rdx
callq 0x15650
testl %eax, %eax
pushq $0x6
popq %r12
je 0x1d09c
movq %rbx, %rdi
leaq 0xe4c78(%rip), %rsi     # 0x101cee
movq %r12, %rdx
callq 0x15650
testl %eax, %eax
je 0x1d09c
movq %rbx, %rdi
leaq 0xcfb3b(%rip), %rsi     # 0xecbc7
movq %r12, %rdx
callq 0x15650
testl %eax, %eax
jne 0x1d42a
movq %rbx, %rdi
leaq 0xcfb21(%rip), %rsi     # 0xecbc7
movq %r12, %rdx
callq 0x15650
testl %eax, %eax
je 0x1d196
subq $0x8, %rsp
leaq 0xa48(%rsp), %rdi
leaq 0xd020e(%rip), %rsi     # 0xed2d7
movq %rbx, %rdx
leaq 0x248(%rsp), %rcx
leaq 0x648(%rsp), %r8
leaq 0x18(%rsp), %rbx
movq %rbx, %r9
xorl %eax, %eax
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
callq 0x155f0
addq $0x80, %rsp
cmpl $0x13, %eax
je 0x1d284
jmp 0x1d4bd
subq $0x8, %rsp
leaq 0xa48(%rsp), %rdi
leaq 0xcfa24(%rip), %rsi     # 0xecbcd
movq %rbx, %rdx
leaq 0x248(%rsp), %rcx
leaq 0xc0(%rsp), %r8
leaq 0x648(%rsp), %r9
xorl %eax, %eax
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %r10
pushq %r10
leaq 0x90(%rsp), %rbx
pushq %rbx
leaq 0x138(%rsp), %r10
pushq %r10
callq 0x155f0
addq $0x90, %rsp
cmpl $0x15, %eax
jne 0x1d4bd
movl %ebp, 0xc(%rsp)
leaq 0x2a40(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x7e598
movq %r15, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x7c534
cmpl $0x0, 0x8(%rsp)
je 0x1d2bc
leaq 0x138(%rsp), %rdi
callq 0x7ebd2
movl $0x418, %edx            # imm = 0x418
leaq 0x3a40(%rsp), %rbx
movq %rbx, %rdi
leaq 0x240(%rsp), %rsi
callq 0x15310
movq %rbx, %rdi
pushq $0x2f
popq %rsi
callq 0x156b0
movq %rax, %rbp
testq %rax, %rax
cmoveq %rbx, %rbp
movq %rbp, %rdi
pushq $0x2e
popq %rsi
callq 0x156b0
testq %rax, %rax
je 0x1d301
movb $0x0, (%rax)
leaq 0x2a40(%rsp), %rbx
movq %rbx, %rdi
leaq 0xcf914(%rip), %rsi     # 0xecc27
movq %rbp, %rdx
xorl %eax, %eax
callq 0x15110
movq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x36436
movq %rax, %r12
movq 0xa0(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x3d942
movq %rax, %rbx
movq %r13, %rdi
movq %rbp, %rsi
callq 0x3d996
movq %rax, %rbp
testq %rax, %rax
je 0x1d37d
leaq 0x30(%rbp), %rsi
movq %r14, %rdi
callq 0x7cc00
movq %r14, %rdi
movq %r15, %rsi
callq 0x7cdb2
movq (%rbp), %rax
movq %rbp, %rdi
movq %r14, %rsi
callq *0x58(%rax)
testq %rbx, %rbx
movq 0x98(%rsp), %r13
movl 0xc(%rsp), %ebp
je 0x1d3b1
leaq 0x28(%rbx), %rsi
movq %r14, %rdi
callq 0x7cc00
movq %r14, %rdi
movq %r15, %rsi
callq 0x7cdb2
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
callq *0x10(%rax)
testq %r12, %r12
je 0x1d420
movq %r14, %rdi
callq 0xafa1e
movq %r14, %rdi
movq %r12, %rsi
callq 0x1da20
movslq 0xdc(%rsp), %rax
testq %rax, %rax
je 0x1d418
movq 0xd0(%rsp), %rcx
movq -0x8(%rcx,%rax,8), %rbx
movq %r14, %rdi
callq 0x1e20e
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
callq *0x38(%rax)
xorl %r12d, %r12d
movslq 0x3c(%rbx), %rax
cmpq %rax, %r12
jge 0x1d3c9
movq 0x30(%rbx), %rax
movq (%rax,%r12,8), %rsi
movq %r14, %rdi
callq 0x1da20
incq %r12
jmp 0x1d3fa
movq %r14, %rdi
callq 0xafa8c
incl %ebp
movq %r15, %rdi
callq 0x7c582
leaq 0xa40(%rsp), %rbx
jmp 0x1cffd
leaq 0xcf66c(%rip), %rdi     # 0xecaaa
xorl %ebx, %ebx
xorl %eax, %eax
callq 0xb2096
jmp 0x1d4d9
movq %r13, %rdi
callq 0x15610
pushq $0x1
popq %rbx
cmpl $0x0, 0x13c97e(%rip)    # 0x159ddc
je 0x1d4d9
leaq 0xcfa14(%rip), %rdi     # 0xece7b
callq 0x15990
leaq 0xc0(%rsp), %rdi
callq 0xaf510
leaq 0xcf121(%rip), %rdi     # 0xec5a1
movb $0x1, %al
callq 0x15080
leaq 0xcf225(%rip), %rdi     # 0xec6b3
movl %ebp, %esi
xorl %eax, %eax
callq 0x15080
movq 0x13bae2(%rip), %rax    # 0x158f80
movq (%rax), %rdi
callq 0x15750
jmp 0x1d4d9
leaq 0xcf6f5(%rip), %rdi     # 0xecba4
xorl %ebx, %ebx
movq %r14, %rsi
xorl %eax, %eax
callq 0xb2096
jmp 0x1d4d9
leaq 0xcf746(%rip), %rdi     # 0xecc0a
xorl %ebx, %ebx
movl 0x4(%rsp), %esi
movq 0x90(%rsp), %rdx
xorl %eax, %eax
callq 0xb2096
movl %ebx, %eax
addq $0x4248, %rsp           # imm = 0x4248
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1d502
jmp 0x1d4fb
jmp 0x1d4fb
jmp 0x1d4fb
jmp 0x1d4fb
jmp 0x1d4fb
jmp 0x1d4fb
movq %rax, %rbx
jmp 0x1d512
jmp 0x1d502
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0xafa8c
leaq 0x130(%rsp), %rdi
callq 0x7c582
movq %rbx, %rdi
callq 0x15af0