// File: /workspace/github_cpp_makefile_star2_O1/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, 0x14(%rsp)
movq %rsi, %r15
movq %rdi, %r12
leaq 0xc0(%rsp), %r14
movq %r14, %rdi
callq 0xc2368
xorl %ebx, %ebx
movq %r14, %rdi
xorl %esi, %esi
callq 0x15a20
movq 0x8(%r12), %rax
movq %rax, 0x28(%rsp)
testq %rax, %rax
je 0x1d5ca
leaq 0xfa1ba(%rip), %rsi     # 0x117273
movq %r15, %rdi
callq 0x15770
testq %rax, %rax
je 0x1d5dd
leaq 0x3240(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq %rax, 0x8(%rsp)
movq %rax, %rdx
callq 0x159e0
testq %rax, %rax
je 0x1d5f2
movq %r12, 0x20(%rsp)
movq %r15, 0x18(%rsp)
leaq 0xf51fb(%rip), %r12     # 0x1122f9
leaq 0x3240(%rsp), %rdi
leaq 0xd0(%rsp), %rbp
movl $0x0, (%rsp)
xorl %ebx, %ebx
movq 0x8(%rsp), %r15
incl %ebx
movq %rdi, %r14
movq %r12, %rsi
leaq 0x640(%rsp), %rdx
xorl %eax, %eax
callq 0x155f0
movl $0x2, %ecx
cmpl $0x1, %eax
jne 0x1d5a3
cmpb $0x23, 0x640(%rsp)
je 0x1d5a3
movl 0x640(%rsp), %eax
movl $0x6e616373, %ecx       # imm = 0x6E616373
xorl %ecx, %eax
movzbl 0x644(%rsp), %ecx
orl %eax, %ecx
leaq 0x30(%rsp), %r11
je 0x1d1ae
movl 0x640(%rsp), %eax
movl $0x67616d69, %ecx       # imm = 0x67616D69
xorl %ecx, %eax
movzwl 0x644(%rsp), %ecx
xorl $0x65, %ecx
orl %eax, %ecx
je 0x1d1ae
movl 0x640(%rsp), %eax
movl $0x6d617266, %ecx       # imm = 0x6D617266
xorl %ecx, %eax
movzwl 0x644(%rsp), %edx
xorl $0x65, %edx
xorl %ecx, %ecx
orl %eax, %edx
jne 0x1d5a3
movl %ebx, 0x4(%rsp)
movl 0x640(%rsp), %eax
movl $0x6d617266, %ecx       # imm = 0x6D617266
xorl %ecx, %eax
movzwl 0x644(%rsp), %ecx
xorl $0x65, %ecx
orl %eax, %ecx
je 0x1d2b1
subq $0x8, %rsp
movq %r14, %rdi
leaq 0xed194(%rip), %rsi     # 0x10a375
leaq 0x648(%rsp), %rdx
leaq 0x248(%rsp), %rcx
leaq 0x1648(%rsp), %r8
movq %r11, %r9
xorl %eax, %eax
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
movq %r11, %rbx
callq 0x155f0
addq $0x80, %rsp
cmpl $0x13, %eax
je 0x1d39b
jmp 0x1d585
subq $0x8, %rsp
movq %r14, %rdi
leaq 0xec928(%rip), %rsi     # 0x109be7
leaq 0x648(%rsp), %rdx
leaq 0x248(%rsp), %rcx
leaq 0xc0(%rsp), %r8
leaq 0x1648(%rsp), %r9
xorl %eax, %eax
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
leaq 0xb0(%rsp), %r10
pushq %r10
pushq %r11
leaq 0x138(%rsp), %r10
pushq %r10
movq %r11, %rbx
callq 0x155f0
addq $0x90, %rsp
cmpl $0x15, %eax
jne 0x1d585
leaq 0x1a40(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x8b64a
leaq 0x130(%rsp), %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x891ca
cmpl $0x0, 0x14(%rsp)
je 0x1d3d4
leaq 0x138(%rsp), %rdi
callq 0x8bd98
movl $0x418, %edx            # imm = 0x418
leaq 0x2a40(%rsp), %rbx
movq %rbx, %rdi
leaq 0x240(%rsp), %rsi
callq 0x15300
movq %rbx, %rdi
movl $0x2f, %esi
callq 0x156a0
movq %rax, %r12
testq %rax, %rax
cmoveq %rbx, %r12
movq %r12, %rdi
movl $0x2e, %esi
callq 0x156a0
testq %rax, %rax
je 0x1d41d
movb $0x0, (%rax)
leaq 0x1a40(%rsp), %rbx
movq %rbx, %rdi
leaq 0xec812(%rip), %rsi     # 0x109c41
movq %r12, %rdx
xorl %eax, %eax
callq 0x15110
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x3aaf0
movq %rax, %r13
movq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x42fb0
movq %rax, %rbx
movq %r15, %rdi
movq %r12, %rsi
callq 0x4301a
movq %rax, %r12
testq %rax, %rax
je 0x1d499
leaq 0x30(%r12), %rsi
movq %rbp, %rdi
callq 0x898e2
movq %rbp, %rdi
leaq 0x130(%rsp), %rsi
callq 0x89b10
movq (%r12), %rax
movq %r12, %rdi
movq %rbp, %rsi
callq *0x58(%rax)
testq %rbx, %rbx
movq 0x8(%rsp), %r15
leaq 0xf4e51(%rip), %r12     # 0x1122f9
je 0x1d4d2
leaq 0x28(%rbx), %rsi
movq %rbp, %rdi
callq 0x898e2
movq %rbp, %rdi
leaq 0x130(%rsp), %rsi
callq 0x89b10
movq (%rbx), %rax
movq %rbx, %rdi
movq %rbp, %rsi
callq *0x10(%rax)
testq %r13, %r13
je 0x1d56d
movq %rbp, %rdi
callq 0xc2904
movl 0xdc(%rsp), %edx
movq %rbp, %rdi
movq %r13, %rsi
callq 0xc299a
movl 0xdc(%rsp), %eax
testl %eax, %eax
je 0x1d559
movq 0xd0(%rsp), %rcx
movslq %eax, %rsi
movq -0x8(%rcx,%rsi,8), %rbx
decl %esi
movq %rbp, %rdi
callq 0xc2b0e
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x130(%rsp), %rsi
callq *0x38(%rax)
cmpl $0x0, 0x3c(%rbx)
jle 0x1d4f5
xorl %r12d, %r12d
movq 0x30(%rbx), %rax
movq (%rax,%r12,8), %rsi
movl 0xdc(%rsp), %edx
movq %rbp, %rdi
callq 0xc299a
incq %r12
movslq 0x3c(%rbx), %rax
cmpq %rax, %r12
jl 0x1d534
jmp 0x1d4f5
movq %rbp, %rdi
callq 0xc296e
movq 0x8(%rsp), %r15
leaq 0xf4d8c(%rip), %r12     # 0x1122f9
incl (%rsp)
leaq 0x130(%rsp), %rdi
callq 0x89218
xorl %ecx, %ecx
movl 0x4(%rsp), %ebx
jmp 0x1d5a3
leaq 0xec698(%rip), %rdi     # 0x109c24
movl 0x4(%rsp), %ebx
movl %ebx, %esi
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0xc5782
movl $0x1, %ecx
testb $0x1, %cl
jne 0x1d65d
movq %r14, %rdi
movl $0x1000, %esi           # imm = 0x1000
movq %r15, %rdx
callq 0x159e0
movq %r14, %rdi
testq %rax, %rax
jne 0x1d11c
jmp 0x1d5fe
leaq 0xec4f3(%rip), %rdi     # 0x109ac4
xorl %eax, %eax
callq 0xc5782
jmp 0x1d65f
leaq 0xec5da(%rip), %rdi     # 0x109bbe
xorl %ebx, %ebx
movq %r15, %rsi
xorl %eax, %eax
callq 0xc5782
jmp 0x1d65f
movl $0x0, (%rsp)
movq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x15600
movl $0x1, %ebx
cmpl $0x0, 0x1517ba(%rip)    # 0x16edcc
je 0x1d65f
leaq 0xec87a(%rip), %rdi     # 0x109e95
callq 0x15980
leaq 0xc0(%rsp), %rdi
callq 0xc23ca
leaq 0xebf85(%rip), %rdi     # 0x1095b9
movb $0x1, %al
callq 0x15080
leaq 0xec089(%rip), %rdi     # 0x1096cb
movl (%rsp), %esi
xorl %eax, %eax
callq 0x15080
movq 0x15090d(%rip), %rax    # 0x16df60
movq (%rax), %rdi
callq 0x15760
jmp 0x1d65f
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x4248, %rsp           # imm = 0x4248
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1d688
jmp 0x1d681
jmp 0x1d681
jmp 0x1d681
jmp 0x1d681
jmp 0x1d681
jmp 0x1d681
movq %rax, %rbx
jmp 0x1d698
jmp 0x1d688
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0xc296e
leaq 0x130(%rsp), %rdi
callq 0x89218
movq %rbx, %rdi
callq 0x15ae0