// File: 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 $0x44d8, %rsp           # imm = 0x44D8
movq %rdi, 0x44c8(%rsp)
movq %rsi, 0x44c0(%rsp)
movl %edx, 0x44bc(%rsp)
leaq 0x44a8(%rsp), %rdi
callq 0x16dd30
leaq 0x44a8(%rsp), %rdi
callq 0x263f0
movl $0x0, 0x44a4(%rsp)
movq 0x44c8(%rsp), %rdi
callq 0x26780
movq %rax, 0x4498(%rsp)
cmpq $0x0, 0x4498(%rsp)
jne 0x22d4b
leaq 0x1d5e2a(%rip), %rdi    # 0x1f8b5e
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0x44d4(%rsp)
jmp 0x236c1
movq 0x44c0(%rsp), %rdi
leaq 0x1df479(%rip), %rsi    # 0x2021d3
callq 0x168d0
movq %rax, 0x4490(%rsp)
cmpq $0x0, 0x4490(%rsp)
jne 0x22d98
movq 0x44c0(%rsp), %rsi
leaq 0x1d5eed(%rip), %rdi    # 0x1f8c6e
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0x44d4(%rsp)
jmp 0x236c1
movl $0x0, 0x348c(%rsp)
leaq 0x3490(%rsp), %rdi
movq 0x4490(%rsp), %rdx
movl $0x1000, %esi           # imm = 0x1000
callq 0x16b90
cmpq $0x0, %rax
je 0x23653
movl 0x348c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x348c(%rsp)
leaq 0x3490(%rsp), %rdi
leaq 0x2480(%rsp), %rdx
leaq 0x1da0a4(%rip), %rsi    # 0x1fce93
movb $0x0, %al
callq 0x16710
cmpl $0x1, %eax
je 0x22dfd
jmp 0x22da3
movsbl 0x2480(%rsp), %eax
cmpl $0x23, %eax
jne 0x22e0c
jmp 0x22da3
leaq 0x2480(%rsp), %rdi
leaq 0x1de5bf(%rip), %rsi    # 0x2013da
callq 0x16a80
cmpl $0x0, %eax
je 0x22e5b
leaq 0x2480(%rsp), %rdi
leaq 0x1e72e6(%rip), %rsi    # 0x20a11a
callq 0x16a80
cmpl $0x0, %eax
je 0x22e5b
leaq 0x2480(%rsp), %rdi
leaq 0x1d5e44(%rip), %rsi    # 0x1f8c91
callq 0x16a80
cmpl $0x0, %eax
jne 0x2364e
leaq 0x2480(%rsp), %rdi
leaq 0x1d5e27(%rip), %rsi    # 0x1f8c91
callq 0x16a80
cmpl $0x0, %eax
jne 0x23080
leaq 0x3490(%rsp), %rdi
leaq 0x2480(%rsp), %rdx
leaq 0x1ff0(%rsp), %rcx
leaq 0x1bf0(%rsp), %r9
leaq 0x2400(%rsp), %rax
movq %rax, 0x108(%rsp)
leaq 0x2400(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x110(%rsp)
leaq 0x2400(%rsp), %rax
addq $0x10, %rax
movq %rax, 0x118(%rsp)
leaq 0x2400(%rsp), %rax
addq $0x18, %rax
movq %rax, 0x120(%rsp)
leaq 0x2400(%rsp), %rax
addq $0x20, %rax
movq %rax, 0x128(%rsp)
leaq 0x2400(%rsp), %rax
addq $0x28, %rax
movq %rax, 0x130(%rsp)
leaq 0x2400(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x138(%rsp)
leaq 0x2400(%rsp), %rbp
addq $0x38, %rbp
leaq 0x2400(%rsp), %r13
addq $0x40, %r13
leaq 0x2400(%rsp), %r12
addq $0x48, %r12
leaq 0x2400(%rsp), %r15
addq $0x50, %r15
leaq 0x2400(%rsp), %r14
addq $0x58, %r14
leaq 0x2400(%rsp), %rbx
addq $0x60, %rbx
leaq 0x2400(%rsp), %r11
addq $0x68, %r11
leaq 0x2400(%rsp), %r10
addq $0x70, %r10
leaq 0x2400(%rsp), %rax
addq $0x78, %rax
movq %rax, 0x140(%rsp)
leaq 0x1d5cfc(%rip), %rsi    # 0x1f8c97
leaq 0x23f8(%rsp), %r8
leaq 0x23f0(%rsp), %rax
movq %rax, (%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x118(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x140(%rsp), %rax
movq %rbp, 0x40(%rsp)
movq %r13, 0x48(%rsp)
movq %r12, 0x50(%rsp)
movq %r15, 0x58(%rsp)
movq %r14, 0x60(%rsp)
movq %rbx, 0x68(%rsp)
movq %r11, 0x70(%rsp)
movq %r10, 0x78(%rsp)
movq %rax, 0x80(%rsp)
movb $0x0, %al
callq 0x16710
cmpl $0x15, %eax
je 0x2307b
movl 0x348c(%rsp), %esi
movq 0x44c0(%rsp), %rdx
leaq 0x1d5c70(%rip), %rdi    # 0x1f8cd4
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0x44d4(%rsp)
jmp 0x236c1
jmp 0x23248
leaq 0x3490(%rsp), %rdi
leaq 0x2480(%rsp), %rdx
leaq 0x1ff0(%rsp), %rcx
leaq 0x1bf0(%rsp), %r8
leaq 0x2400(%rsp), %r9
leaq 0x2400(%rsp), %rax
addq $0x8, %rax
leaq 0x2400(%rsp), %rsi
addq $0x10, %rsi
movq %rsi, 0xd8(%rsp)
leaq 0x2400(%rsp), %rsi
addq $0x18, %rsi
movq %rsi, 0xe0(%rsp)
leaq 0x2400(%rsp), %rsi
addq $0x20, %rsi
movq %rsi, 0xe8(%rsp)
leaq 0x2400(%rsp), %rsi
addq $0x28, %rsi
movq %rsi, 0xf0(%rsp)
leaq 0x2400(%rsp), %rsi
addq $0x30, %rsi
movq %rsi, 0xf8(%rsp)
leaq 0x2400(%rsp), %rbp
addq $0x38, %rbp
leaq 0x2400(%rsp), %r13
addq $0x40, %r13
leaq 0x2400(%rsp), %r12
addq $0x48, %r12
leaq 0x2400(%rsp), %r15
addq $0x50, %r15
leaq 0x2400(%rsp), %r14
addq $0x58, %r14
leaq 0x2400(%rsp), %rbx
addq $0x60, %rbx
leaq 0x2400(%rsp), %r11
addq $0x68, %r11
leaq 0x2400(%rsp), %r10
addq $0x70, %r10
leaq 0x2400(%rsp), %rsi
addq $0x78, %rsi
movq %rsi, 0x100(%rsp)
leaq 0x1d619a(%rip), %rsi    # 0x1f932d
movq %rax, (%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x100(%rsp), %rax
movq %rbp, 0x30(%rsp)
movq %r13, 0x38(%rsp)
movq %r12, 0x40(%rsp)
movq %r15, 0x48(%rsp)
movq %r14, 0x50(%rsp)
movq %rbx, 0x58(%rsp)
movq %r11, 0x60(%rsp)
movq %r10, 0x68(%rsp)
movq %rax, 0x70(%rsp)
movb $0x0, %al
callq 0x16710
cmpl $0x13, %eax
je 0x23246
movl 0x348c(%rsp), %esi
movq 0x44c0(%rsp), %rdx
leaq 0x1d5aa5(%rip), %rdi    # 0x1f8cd4
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0x44d4(%rsp)
jmp 0x236c1
jmp 0x23248
leaq 0x2400(%rsp), %rsi
leaq 0x1a60(%rsp), %rdi
callq 0x106bb0
leaq 0x1ae0(%rsp), %rdi
leaq 0x1a60(%rsp), %rsi
xorl %edx, %edx
callq 0x1022c0
cmpl $0x0, 0x44bc(%rsp)
je 0x232a8
leaq 0x1ae0(%rsp), %rdi
callq 0x29c30
jmp 0x2328d
jmp 0x232a8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a58(%rsp)
movl %eax, 0x1a54(%rsp)
jmp 0x2363c
leaq 0x1250(%rsp), %rdi
leaq 0x1ff0(%rsp), %rsi
movl $0x418, %edx            # imm = 0x418
callq 0x16380
leaq 0x1250(%rsp), %rdi
movl $0x2f, %esi
callq 0x16810
movq %rax, 0x1248(%rsp)
cmpq $0x0, 0x1248(%rsp)
jne 0x232f7
leaq 0x1250(%rsp), %rax
movq %rax, 0x1248(%rsp)
movq 0x1248(%rsp), %rdi
movl $0x2e, %esi
callq 0x16810
movq %rax, 0x1240(%rsp)
cmpq $0x0, 0x1240(%rsp)
je 0x23327
movq 0x1240(%rsp), %rax
movb $0x0, (%rax)
movq 0x1248(%rsp), %rdx
leaq 0x1d59bb(%rip), %rsi    # 0x1f8cf1
xorl %eax, %eax
leaq 0x240(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
callq 0x16130
movq 0xc8(%rsp), %rsi
movq 0x4498(%rsp), %rdi
callq 0x60280
movq %rax, 0xd0(%rsp)
jmp 0x2336c
movq 0xd0(%rsp), %rax
movq %rax, 0x238(%rsp)
movq 0x44c8(%rsp), %rdi
movq 0x1248(%rsp), %rsi
callq 0x71150
movq %rax, 0xc0(%rsp)
jmp 0x2339b
movq 0xc0(%rsp), %rax
movq %rax, 0x230(%rsp)
movq 0x44c8(%rsp), %rdi
movq 0x1248(%rsp), %rsi
callq 0x71200
movq %rax, 0xb8(%rsp)
jmp 0x233ca
movq 0xb8(%rsp), %rax
movq %rax, 0x228(%rsp)
cmpq $0x0, 0x228(%rsp)
je 0x23447
movq 0x228(%rsp), %rdi
callq 0x29c50
movq %rax, 0xb0(%rsp)
jmp 0x233fc
movq 0xb0(%rsp), %rsi
leaq 0x1c8(%rsp), %rdi
callq 0x103370
jmp 0x23413
leaq 0x1c8(%rsp), %rdi
leaq 0x1ae0(%rsp), %rsi
callq 0x1036f0
jmp 0x2342a
movq 0x228(%rsp), %rdi
movq (%rdi), %rax
movq 0x58(%rax), %rax
leaq 0x1c8(%rsp), %rsi
callq *%rax
jmp 0x23445
jmp 0x23447
cmpq $0x0, 0x230(%rsp)
je 0x234b4
movq 0x230(%rsp), %rdi
callq 0x29c60
movq %rax, 0xa8(%rsp)
jmp 0x23469
movq 0xa8(%rsp), %rsi
leaq 0x168(%rsp), %rdi
callq 0x103370
jmp 0x23480
leaq 0x168(%rsp), %rdi
leaq 0x1ae0(%rsp), %rsi
callq 0x1036f0
jmp 0x23497
movq 0x230(%rsp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
leaq 0x168(%rsp), %rsi
callq *%rax
jmp 0x234b2
jmp 0x234b4
cmpq $0x0, 0x238(%rsp)
je 0x2361c
leaq 0x158(%rsp), %rdi
callq 0x276f0
jmp 0x234d2
movq 0x238(%rsp), %rsi
leaq 0x158(%rsp), %rdi
callq 0x29c70
jmp 0x234e9
jmp 0x234eb
leaq 0x158(%rsp), %rdi
callq 0x29ca0
movl %eax, 0xa4(%rsp)
jmp 0x23501
movl 0xa4(%rsp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x23519
jmp 0x2360f
leaq 0x158(%rsp), %rdi
callq 0x29cc0
movq %rax, 0x98(%rsp)
jmp 0x23530
movq 0x98(%rsp), %rax
movq %rax, 0x150(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x29cd0
jmp 0x2354f
movq 0x150(%rsp), %rdi
movq (%rdi), %rax
movq 0x38(%rax), %rax
leaq 0x1ae0(%rsp), %rsi
callq *%rax
jmp 0x2356a
movl $0x0, 0x14c(%rsp)
movl 0x14c(%rsp), %eax
movl %eax, 0x94(%rsp)
movq 0x150(%rsp), %rdi
callq 0x26380
movl %eax, %ecx
movl 0x94(%rsp), %eax
cmpl %ecx, %eax
jge 0x2360a
movq 0x150(%rsp), %rdi
movl 0x14c(%rsp), %esi
callq 0x29d20
movq %rax, 0x88(%rsp)
jmp 0x235bb
movq 0x88(%rsp), %rsi
leaq 0x158(%rsp), %rdi
callq 0x29cf0
jmp 0x235d2
jmp 0x235d4
movl 0x14c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14c(%rsp)
jmp 0x23575
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a58(%rsp)
movl %eax, 0x1a54(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x277c0
jmp 0x2363c
jmp 0x234eb
leaq 0x158(%rsp), %rdi
callq 0x277c0
movl 0x44a4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44a4(%rsp)
leaq 0x1ae0(%rsp), %rdi
callq 0x102360
jmp 0x2364e
leaq 0x1ae0(%rsp), %rdi
callq 0x102360
jmp 0x236da
jmp 0x22da3
movq 0x4490(%rsp), %rdi
callq 0x16730
cmpl $0x0, 0x241159(%rip)    # 0x2647c0
je 0x236b6
leaq 0x1d5689(%rip), %rdi    # 0x1f8cf9
movb $0x0, %al
callq 0x16090
leaq 0x44a8(%rsp), %rdi
callq 0x16ddf0
leaq 0x1d4ef4(%rip), %rdi    # 0x1f857f
movb $0x1, %al
callq 0x16090
movl 0x44a4(%rsp), %esi
leaq 0x1d501d(%rip), %rdi    # 0x1f86bd
movb $0x0, %al
callq 0x16090
movq 0x2378e2(%rip), %rax    # 0x25af90
movq (%rax), %rdi
callq 0x168c0
movl $0x1, 0x44d4(%rsp)
movl 0x44d4(%rsp), %eax
addq $0x44d8, %rsp           # imm = 0x44D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1a58(%rsp), %rdi
callq 0x16ca0
nopw (%rax,%rax)