// File: tomfunkhouser[P]gaps/apps/sflprocess/sflprocess.cpp
// Function: CreateLabeledObjectInstances(gaps::R3SurfelScene*, char const*, char const*, char const*)
static int
CreateLabeledObjectInstances(R3SurfelScene *scene, const char *csv_filename,
   const char *parent_object_name, const char *parent_node_name)
{
  // Get convenient variables
  R3SurfelTree *tree = scene->Tree();
  if (!tree) return 0;
  R3SurfelDatabase *database = tree->Database();
  if (!database) return 0;

  // Find parent object
  R3SurfelObject *parent_object = scene->RootObject();
  if (strcmp(parent_object_name, "Root")) {
    parent_object = scene->FindObjectByName(parent_object_name);
    if (!parent_object) {
      RNFail("Unable to find parent object with name %s\n", parent_object_name);
      return 0;
    }
  }

  // Find parent node
  R3SurfelNode *parent_node = tree->RootNode();
  if (strcmp(parent_node_name, "Root")) {
    parent_node = tree->FindNodeByName(parent_node_name);
    if (!parent_node) {
      RNFail("Unable to find parent node with name %s\n", parent_node_name);
      return 0;
    }
  }

  // Initialize identifier maps
  int max_surfel_identifier = scene->Tree()->Database()->MaxIdentifier();
  std::vector<int> label_identifiers(max_surfel_identifier+1);
  std::vector<int> instance_identifiers(max_surfel_identifier+1);
  label_identifiers.assign(max_surfel_identifier+1, -1);
  instance_identifiers.assign(max_surfel_identifier+1, -1);

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

  // Read csv file
  int surfel_identifier, label_identifier, instance_identifier;
  while (fscanf(fp, "%d,%d,%d", &surfel_identifier,
    &label_identifier, &instance_identifier) == (unsigned int) 3) {
    if (surfel_identifier < 0) continue;
    if (surfel_identifier > max_surfel_identifier) continue;
    // if (label_identifier == 255) label_identifier = -1; // TEMPORARY
    label_identifiers[surfel_identifier] = label_identifier;
    instance_identifiers[surfel_identifier] = instance_identifier;
  }

  // Close csv file
  fclose(fp);

  // Remove current objects
  RemoveObjects(scene);

  // Create new objects
  if (!CreateObjects(scene, instance_identifiers,
    parent_object, parent_node, FALSE)) return 0;

  // Assign object labels
  for (unsigned int i = 0; i < instance_identifiers.size(); i++) {
    // Find label
    int label_identifier = label_identifiers[i];
    if (label_identifier < 0) continue;
    R3SurfelLabel *label = scene->FindLabelByIdentifier(label_identifier);
    if (!label) continue;

    // Find object
    int instance_identifier = instance_identifiers[i];
    if (instance_identifier < 0) continue;
    R3SurfelObject *object = scene->FindObjectByIdentifier(instance_identifier);
    if (!object) continue;

    // Check assignment
    RNScalar confidence = 0.5;
    int originator = R3_SURFEL_MACHINE_ORIGINATOR;
    R3SurfelLabelAssignment *assignment = scene->FindLabelAssignment(object, label, confidence, originator);
    if (assignment) continue;

    // Create assignment
    assignment = new R3SurfelLabelAssignment(object, label, confidence, originator);
    scene->InsertLabelAssignment(assignment);
  }

  // Return success
  return 1;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x148(%rsp)
movq %rsi, 0x140(%rsp)
movq %rdx, 0x138(%rsp)
movq %rcx, 0x130(%rsp)
movq 0x148(%rsp), %rdi
callq 0x26780
movq %rax, 0x128(%rsp)
cmpq $0x0, 0x128(%rsp)
jne 0x24277
movl $0x0, 0x154(%rsp)
jmp 0x248d7
movq 0x128(%rsp), %rdi
callq 0x26790
movq %rax, 0x120(%rsp)
cmpq $0x0, 0x120(%rsp)
jne 0x242a7
movl $0x0, 0x154(%rsp)
jmp 0x248d7
movq 0x148(%rsp), %rdi
callq 0x2a290
movq %rax, 0x118(%rsp)
movq 0x138(%rsp), %rdi
leaq 0x1db913(%rip), %rsi    # 0x1ffbde
callq 0x16a80
cmpl $0x0, %eax
je 0x24325
movq 0x148(%rsp), %rdi
movq 0x138(%rsp), %rsi
callq 0x70d50
movq %rax, 0x118(%rsp)
cmpq $0x0, 0x118(%rsp)
jne 0x24323
movq 0x138(%rsp), %rsi
leaq 0x1d443b(%rip), %rdi    # 0x1f8747
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0x154(%rsp)
jmp 0x248d7
jmp 0x24325
movq 0x128(%rsp), %rdi
callq 0x276d0
movq %rax, 0x110(%rsp)
movq 0x130(%rsp), %rdi
leaq 0x1db895(%rip), %rsi    # 0x1ffbde
callq 0x16a80
cmpl $0x0, %eax
je 0x243a3
movq 0x128(%rsp), %rdi
movq 0x130(%rsp), %rsi
callq 0x60280
movq %rax, 0x110(%rsp)
cmpq $0x0, 0x110(%rsp)
jne 0x243a1
movq 0x130(%rsp), %rsi
leaq 0x1d437b(%rip), %rdi    # 0x1f8705
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0x154(%rsp)
jmp 0x248d7
jmp 0x243a3
movq 0x148(%rsp), %rdi
callq 0x26780
movq %rax, %rdi
callq 0x26790
movq %rax, %rdi
callq 0x2a2b0
movl %eax, 0x10c(%rsp)
movl 0x10c(%rsp), %eax
incl %eax
cltq
movq %rax, 0x50(%rsp)
leaq 0xef(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x2a2d0
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
leaq 0xf0(%rsp), %rdi
callq 0x2a2e0
jmp 0x24402
leaq 0xef(%rsp), %rdi
callq 0x2a360
movl 0x10c(%rsp), %eax
incl %eax
cltq
movq %rax, 0x40(%rsp)
leaq 0xbf(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x2a2d0
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rdx
leaq 0xc0(%rsp), %rdi
callq 0x2a2e0
jmp 0x2444a
leaq 0xbf(%rsp), %rdi
callq 0x2a360
movl 0x10c(%rsp), %eax
incl %eax
movslq %eax, %rsi
movl $0xffffffff, 0xb8(%rsp) # imm = 0xFFFFFFFF
leaq 0xf0(%rsp), %rdi
leaq 0xb8(%rsp), %rdx
callq 0x2a370
jmp 0x24485
movl 0x10c(%rsp), %eax
incl %eax
movslq %eax, %rsi
movl $0xffffffff, 0xb4(%rsp) # imm = 0xFFFFFFFF
leaq 0xc0(%rsp), %rdi
leaq 0xb4(%rsp), %rdx
callq 0x2a370
jmp 0x244b3
movq 0x140(%rsp), %rdi
leaq 0x1ddd11(%rip), %rsi    # 0x2021d3
callq 0x168d0
movq %rax, 0x38(%rsp)
jmp 0x244ce
movq 0x38(%rsp), %rax
movq %rax, 0xa8(%rsp)
cmpq $0x0, 0xa8(%rsp)
jne 0x24582
movq 0x140(%rsp), %rsi
leaq 0x1d486b(%rip), %rdi    # 0x1f8d64
xorl %eax, %eax
callq 0x172cb0
jmp 0x24502
movl $0x0, 0x154(%rsp)
movl $0x1, 0xa4(%rsp)
jmp 0x2489f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
leaq 0xef(%rsp), %rdi
callq 0x2a360
jmp 0x248e6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
leaq 0xbf(%rsp), %rdi
callq 0x2a360
jmp 0x248c8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
jmp 0x248bb
jmp 0x24584
movq 0xa8(%rsp), %rdi
leaq 0x1d47ee(%rip), %rsi    # 0x1f8d81
xorl %eax, %eax
leaq 0xa0(%rsp), %rdx
leaq 0x9c(%rsp), %rcx
leaq 0x98(%rsp), %r8
callq 0x16d50
movl %eax, 0x34(%rsp)
jmp 0x245b8
movl 0x34(%rsp), %eax
cmpl $0x3, %eax
jne 0x24630
cmpl $0x0, 0xa0(%rsp)
jge 0x245cd
jmp 0x24584
movl 0xa0(%rsp), %eax
cmpl 0x10c(%rsp), %eax
jle 0x245df
jmp 0x24584
movl 0x9c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movslq 0xa0(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0x2a3a0
movl 0x2c(%rsp), %ecx
movl %ecx, (%rax)
movl 0x98(%rsp), %eax
movl %eax, 0x30(%rsp)
movslq 0xa0(%rsp), %rsi
leaq 0xc0(%rsp), %rdi
callq 0x2a3a0
movl 0x30(%rsp), %ecx
movl %ecx, (%rax)
jmp 0x24584
movq 0xa8(%rsp), %rdi
callq 0x16730
jmp 0x2463f
movq 0x148(%rsp), %rdi
callq 0x89170
jmp 0x2464e
movq 0x148(%rsp), %rdi
movq 0x118(%rsp), %rdx
movq 0x110(%rsp), %rcx
leaq 0xc0(%rsp), %rsi
xorl %r8d, %r8d
movl $0x1, %r9d
callq 0x88930
movl %eax, 0x28(%rsp)
jmp 0x24682
movl 0x28(%rsp), %eax
cmpl $0x0, %eax
jne 0x246a6
movl $0x0, 0x154(%rsp)
movl $0x1, 0xa4(%rsp)
jmp 0x2489f
movl $0x0, 0x94(%rsp)
movl 0x94(%rsp), %eax
movq %rax, 0x20(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x2a3c0
movq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq %rcx, %rax
jae 0x24889
movl 0x94(%rsp), %eax
movl %eax, %esi
leaq 0xf0(%rsp), %rdi
callq 0x2a3a0
movl (%rax), %eax
movl %eax, 0x90(%rsp)
cmpl $0x0, 0x90(%rsp)
jge 0x24709
jmp 0x2484f
movq 0x148(%rsp), %rdi
movl 0x90(%rsp), %esi
callq 0x70f50
movq %rax, 0x18(%rsp)
jmp 0x24724
movq 0x18(%rsp), %rax
movq %rax, 0x88(%rsp)
cmpq $0x0, 0x88(%rsp)
jne 0x24741
jmp 0x2484f
movl 0x94(%rsp), %eax
movl %eax, %esi
leaq 0xc0(%rsp), %rdi
callq 0x2a3a0
movl (%rax), %eax
movl %eax, 0x84(%rsp)
cmpl $0x0, 0x84(%rsp)
jge 0x2476f
jmp 0x2484f
movq 0x148(%rsp), %rdi
movl 0x84(%rsp), %esi
callq 0x70e00
movq %rax, 0x10(%rsp)
jmp 0x2478a
movq 0x10(%rsp), %rax
movq %rax, 0x78(%rsp)
cmpq $0x0, 0x78(%rsp)
jne 0x247a1
jmp 0x2484f
movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000
movq %rax, 0x70(%rsp)
movl $0x1, 0x6c(%rsp)
movq 0x148(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x88(%rsp), %rdx
movsd 0x70(%rsp), %xmm0
movl 0x6c(%rsp), %ecx
callq 0x71090
movq %rax, 0x8(%rsp)
jmp 0x247e3
movq 0x8(%rsp), %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
je 0x247f7
jmp 0x2484f
movl $0x50, %edi
callq 0x16740
movq %rax, (%rsp)
jmp 0x24807
movq (%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x88(%rsp), %rdx
movsd 0x70(%rsp), %xmm0
movl 0x6c(%rsp), %ecx
callq 0x6fbd0
jmp 0x24829
movq (%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x148(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq (%rdi), %rax
movq 0x80(%rax), %rax
callq *%rax
jmp 0x2484d
jmp 0x2484f
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x246b1
movq (%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
movl $0x50, %esi
callq 0x16750
jmp 0x248bb
movl $0x1, 0x154(%rsp)
movl $0x1, 0xa4(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x2a3e0
leaq 0xf0(%rsp), %rdi
callq 0x2a3e0
jmp 0x248d7
leaq 0xc0(%rsp), %rdi
callq 0x2a3e0
leaq 0xf0(%rsp), %rdi
callq 0x2a3e0
jmp 0x248e6
movl 0x154(%rsp), %eax
addq $0x158, %rsp            # imm = 0x158
retq
movq 0xe0(%rsp), %rdi
callq 0x16ca0
nopw %cs:(%rax,%rax)