// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelUtils.cpp
// Function: gaps::CreateObjects(gaps::R3SurfelScene*, std::vector<int, std::allocator<int>> const&, gaps::R3SurfelObject*, gaps::R3SurfelNode*, int, int)
int
CreateObjects(R3SurfelScene *scene,
  const std::vector<int>& instance_identifiers,
  R3SurfelObject *parent_object, R3SurfelNode *parent_node,
  RNBoolean copy_surfels, RNBoolean release_copied_blocks)
{
  // Get convenient variables
  if (!scene) return 0;
  R3SurfelTree *tree = scene->Tree();
  if (!tree) return 0;
  R3SurfelDatabase *database = tree->Database();
  if (!database) return 0;
  if (!parent_object) parent_object = scene->RootObject();
  if (!parent_object) return 0;
  if (!parent_node) parent_node = tree->RootNode();
  if (!parent_node) return 0;
  if (instance_identifiers.empty()) return 0;

  // Create list of object identifiers
  std::vector<int> object_identifiers;
  std::map<int, int> instance_identifier_map;
  for (unsigned int i = 0; i < instance_identifiers.size(); i++) {
    int instance_identifier = instance_identifiers[i];
    std::map<int, int>::iterator it = instance_identifier_map.find(instance_identifier);
    if (it != instance_identifier_map.end()) continue;
    instance_identifier_map.insert(std::pair<int, int>(instance_identifier, 0));
    object_identifiers.push_back(instance_identifier);
  }

  // Check list of object identifiers
  if (object_identifiers.empty()) return 0;
  
  // Read all blocks
  scene->ReadBlocks();
  
  // Create object for each identifier
  for (unsigned int i = 0; i < object_identifiers.size(); i++) {
    int object_identifier = object_identifiers[i];

    // Create pointset
    R3SurfelPointSet pointset;
    for (int i = 0; i < tree->NNodes(); i++) {
      R3SurfelNode *node = tree->Node(i);
      if (node->NParts() > 0) continue;
      for (int j = 0; j < node->NBlocks(); j++) {
        R3SurfelBlock *block = node->Block(j);
        for (int k = 0; k < block->NSurfels(); k++) {
          const R3Surfel *surfel = block->Surfel(k);

          // Get/check surfel identifier
          int surfel_identifier = surfel->Identifier();
          if (surfel_identifier < 0) continue;
          if (surfel_identifier >= (int) instance_identifiers.size()) continue;

          // Get/check instance identifier
          int instance_identifier = instance_identifiers[surfel_identifier];
          if (instance_identifier < 0) continue;
          if (instance_identifier != object_identifier) continue;

          // Add point to pointset
          R3SurfelPoint point(block, surfel);
          pointset.InsertPoint(point);
        }
      }
    }
    
    // Check pointset
    if (pointset.NPoints() == 0) continue;

    // Create object name
    char object_name[1024];
    sprintf(object_name, "OBJECT#%d", object_identifier);

    // Create object
    R3SurfelObject *object = CreateObject(scene, &pointset,
      parent_object, object_name, parent_node, object_name,
      copy_surfels, release_copied_blocks);
    if (!object) continue;
    
    // Set object identifier
    object->SetIdentifier(object_identifier);

    // Create PCA object property
    R3SurfelObjectProperty *pca = new R3SurfelObjectProperty(R3_SURFEL_OBJECT_PCA_PROPERTY, object);
    scene->InsertObjectProperty(pca);
  }

  // Release all blocks 
  scene->ReleaseBlocks();

  // Return success
  return 1;
}

// Assembly:
subq $0x638, %rsp            # imm = 0x638
movq %rdi, 0x628(%rsp)
movq %rsi, 0x620(%rsp)
movq %rdx, 0x618(%rsp)
movq %rcx, 0x610(%rsp)
movl %r8d, 0x60c(%rsp)
movl %r9d, 0x608(%rsp)
cmpq $0x0, 0x628(%rsp)
jne 0x35ec2
movl $0x0, 0x634(%rsp)
jmp 0x3668e
movq 0x628(%rsp), %rdi
callq 0x16ce0
movq %rax, 0x600(%rsp)
cmpq $0x0, 0x600(%rsp)
jne 0x35ef2
movl $0x0, 0x634(%rsp)
jmp 0x3668e
movq 0x600(%rsp), %rdi
callq 0x16d10
movq %rax, 0x5f8(%rsp)
cmpq $0x0, 0x5f8(%rsp)
jne 0x35f22
movl $0x0, 0x634(%rsp)
jmp 0x3668e
cmpq $0x0, 0x618(%rsp)
jne 0x35f42
movq 0x628(%rsp), %rdi
callq 0x31050
movq %rax, 0x618(%rsp)
cmpq $0x0, 0x618(%rsp)
jne 0x35f5d
movl $0x0, 0x634(%rsp)
jmp 0x3668e
cmpq $0x0, 0x610(%rsp)
jne 0x35f7d
movq 0x600(%rsp), %rdi
callq 0x31030
movq %rax, 0x610(%rsp)
cmpq $0x0, 0x610(%rsp)
jne 0x35f98
movl $0x0, 0x634(%rsp)
jmp 0x3668e
movq 0x620(%rsp), %rdi
callq 0x43780
testb $0x1, %al
jne 0x35fab
jmp 0x35fbb
movl $0x0, 0x634(%rsp)
jmp 0x3668e
leaq 0x5e0(%rsp), %rdi
callq 0x437d0
leaq 0x5b0(%rsp), %rdi
callq 0x437e0
movl $0x0, 0x5ac(%rsp)
movl 0x5ac(%rsp), %eax
movq %rax, 0x98(%rsp)
movq 0x620(%rsp), %rdi
callq 0x437f0
movq %rax, %rcx
movq 0x98(%rsp), %rax
cmpq %rcx, %rax
jae 0x36149
movq 0x620(%rsp), %rdi
movl 0x5ac(%rsp), %eax
movl %eax, %esi
callq 0x43810
movl (%rax), %eax
movl %eax, 0x5a8(%rsp)
leaq 0x5b0(%rsp), %rdi
leaq 0x5a8(%rsp), %rsi
callq 0x43830
movq %rax, 0x90(%rsp)
jmp 0x3604e
movq 0x90(%rsp), %rax
movq %rax, 0x5a0(%rsp)
leaq 0x5b0(%rsp), %rdi
callq 0x43880
movq %rax, 0x588(%rsp)
leaq 0x5a0(%rsp), %rdi
leaq 0x588(%rsp), %rsi
callq 0x43860
testb $0x1, %al
jne 0x3608e
jmp 0x360ac
jmp 0x36133
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x598(%rsp)
movl %eax, 0x594(%rsp)
jmp 0x36672
movl $0x0, 0x57c(%rsp)
leaq 0x580(%rsp), %rdi
leaq 0x5a8(%rsp), %rsi
leaq 0x57c(%rsp), %rdx
callq 0x43900
jmp 0x360d6
leaq 0x5b0(%rsp), %rdi
leaq 0x580(%rsp), %rsi
callq 0x438b0
movb %dl, 0x87(%rsp)
movq %rax, 0x88(%rsp)
jmp 0x360fc
movb 0x87(%rsp), %al
movq 0x88(%rsp), %rcx
movq %rcx, 0x568(%rsp)
movb %al, 0x570(%rsp)
leaq 0x5e0(%rsp), %rdi
leaq 0x5a8(%rsp), %rsi
callq 0x43930
jmp 0x36131
jmp 0x36133
movl 0x5ac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5ac(%rsp)
jmp 0x35fe0
leaq 0x5e0(%rsp), %rdi
callq 0x43780
testb $0x1, %al
jne 0x3615c
jmp 0x36177
movl $0x0, 0x634(%rsp)
movl $0x1, 0x564(%rsp)
jmp 0x36656
movq 0x628(%rsp), %rdi
movq (%rdi), %rax
movq 0x160(%rax), %rax
callq *%rax
jmp 0x3618d
movl $0x0, 0x560(%rsp)
movl 0x560(%rsp), %eax
movq %rax, 0x78(%rsp)
leaq 0x5e0(%rsp), %rdi
callq 0x437f0
movq %rax, %rcx
movq 0x78(%rsp), %rax
cmpq %rcx, %rax
jae 0x3662a
movl 0x560(%rsp), %eax
movl %eax, %esi
leaq 0x5e0(%rsp), %rdi
callq 0x439a0
movl (%rax), %eax
movl %eax, 0x55c(%rsp)
leaq 0x4f8(%rsp), %rdi
callq 0x55df0
jmp 0x361f0
movl $0x0, 0x4f4(%rsp)
movl 0x4f4(%rsp), %eax
movl %eax, 0x70(%rsp)
movq 0x600(%rsp), %rdi
callq 0x16cf0
movl %eax, 0x74(%rsp)
jmp 0x36219
movl 0x70(%rsp), %eax
movl 0x74(%rsp), %ecx
cmpl %ecx, %eax
jge 0x3648a
movq 0x600(%rsp), %rdi
movl 0x4f4(%rsp), %esi
callq 0x30a90
movq %rax, 0x68(%rsp)
jmp 0x36244
movq 0x68(%rsp), %rax
movq %rax, 0x4e8(%rsp)
movq 0x4e8(%rsp), %rdi
callq 0x31660
movl %eax, 0x64(%rsp)
jmp 0x36264
movl 0x64(%rsp), %eax
cmpl $0x0, %eax
jle 0x3628b
jmp 0x36474
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x598(%rsp)
movl %eax, 0x594(%rsp)
jmp 0x3661b
movl $0x0, 0x4e4(%rsp)
movl 0x4e4(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0x4e8(%rsp), %rdi
callq 0x186b0
movl %eax, 0x60(%rsp)
jmp 0x362b4
movl 0x5c(%rsp), %eax
movl 0x60(%rsp), %ecx
cmpl %ecx, %eax
jge 0x36472
movq 0x4e8(%rsp), %rdi
movl 0x4e4(%rsp), %esi
callq 0x186d0
movq %rax, 0x50(%rsp)
jmp 0x362df
movq 0x50(%rsp), %rax
movq %rax, 0x4d8(%rsp)
movl $0x0, 0x4d4(%rsp)
movl 0x4d4(%rsp), %eax
movl %eax, 0x48(%rsp)
movq 0x4d8(%rsp), %rdi
callq 0x1c0e0
movl %eax, 0x4c(%rsp)
jmp 0x36315
movl 0x48(%rsp), %eax
movl 0x4c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x3645a
movq 0x4d8(%rsp), %rdi
movl 0x4d4(%rsp), %esi
callq 0x43660
movq %rax, 0x40(%rsp)
jmp 0x36340
movq 0x40(%rsp), %rax
movq %rax, 0x4c8(%rsp)
movq 0x4c8(%rsp), %rdi
callq 0x31f20
movl %eax, 0x3c(%rsp)
jmp 0x36360
movl 0x3c(%rsp), %eax
movl %eax, 0x4c4(%rsp)
cmpl $0x0, 0x4c4(%rsp)
jge 0x3637a
jmp 0x3641e
movl 0x4c4(%rsp), %eax
movl %eax, 0x38(%rsp)
movq 0x620(%rsp), %rdi
callq 0x437f0
movq %rax, %rcx
movl 0x38(%rsp), %eax
cmpl %ecx, %eax
jl 0x3639f
jmp 0x3641e
movq 0x620(%rsp), %rdi
movslq 0x4c4(%rsp), %rsi
callq 0x43810
movl (%rax), %eax
movl %eax, 0x4c0(%rsp)
cmpl $0x0, 0x4c0(%rsp)
jge 0x363c9
jmp 0x3641e
movl 0x4c0(%rsp), %eax
cmpl 0x55c(%rsp), %eax
je 0x363db
jmp 0x3641e
movq 0x4d8(%rsp), %rsi
movq 0x4c8(%rsp), %rdx
leaq 0x4b0(%rsp), %rdi
callq 0x556c0
jmp 0x363fa
leaq 0x4f8(%rsp), %rdi
leaq 0x4b0(%rsp), %rsi
callq 0x59090
jmp 0x36411
leaq 0x4b0(%rsp), %rdi
callq 0x557a0
movl 0x4d4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4d4(%rsp)
jmp 0x362f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x598(%rsp)
movl %eax, 0x594(%rsp)
leaq 0x4b0(%rsp), %rdi
callq 0x557a0
jmp 0x3661b
jmp 0x3645c
movl 0x4e4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4e4(%rsp)
jmp 0x36296
jmp 0x36474
movl 0x4f4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4f4(%rsp)
jmp 0x361fb
leaq 0x4f8(%rsp), %rdi
callq 0x18700
movl %eax, 0x34(%rsp)
jmp 0x3649d
movl 0x34(%rsp), %eax
cmpl $0x0, %eax
jne 0x364b6
movl $0x7, 0x564(%rsp)
jmp 0x365c4
movl 0x55c(%rsp), %edx
leaq 0x16e686(%rip), %rsi    # 0x1a4b4a
xorl %eax, %eax
leaq 0xb0(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x130f0
movq 0x20(%rsp), %r9
movq 0x628(%rsp), %rdi
movq 0x618(%rsp), %rdx
movq 0x610(%rsp), %r8
movl 0x60c(%rsp), %ecx
movl 0x608(%rsp), %esi
movq %rsp, %rax
movl %esi, 0x8(%rax)
movl %ecx, (%rax)
leaq 0x4f8(%rsp), %rsi
movq %r9, %rcx
callq 0x357d0
movq %rax, 0x28(%rsp)
jmp 0x36522
movq 0x28(%rsp), %rax
movq %rax, 0xa8(%rsp)
cmpq $0x0, 0xa8(%rsp)
jne 0x36547
movl $0x7, 0x564(%rsp)
jmp 0x365c4
movq 0xa8(%rsp), %rdi
movl 0x55c(%rsp), %esi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0x36561
movl $0x30, %edi
callq 0x13570
movq %rax, 0x18(%rsp)
jmp 0x36572
movq 0x18(%rsp), %rdi
movq 0xa8(%rsp), %rdx
xorl %r8d, %r8d
movl %r8d, %ecx
movl $0x1, %esi
callq 0x6d830
jmp 0x36591
movq 0x18(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0x628(%rsp), %rdi
movq 0xa0(%rsp), %rsi
movq (%rdi), %rax
movq 0x40(%rax), %rax
callq *%rax
jmp 0x365b9
movl $0x0, 0x564(%rsp)
leaq 0x4f8(%rsp), %rdi
callq 0x56040
movl 0x564(%rsp), %eax
testl %eax, %eax
je 0x365e0
jmp 0x365de
jmp 0x365e2
jmp 0x365e2
movl 0x560(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x560(%rsp)
jmp 0x36198
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x598(%rsp)
movl %eax, 0x594(%rsp)
movl $0x30, %esi
callq 0x13580
leaq 0x4f8(%rsp), %rdi
callq 0x56040
jmp 0x36672
movq 0x628(%rsp), %rdi
movq (%rdi), %rax
movq 0x168(%rax), %rax
callq *%rax
jmp 0x36640
movl $0x1, 0x634(%rsp)
movl $0x1, 0x564(%rsp)
leaq 0x5b0(%rsp), %rdi
callq 0x439c0
leaq 0x5e0(%rsp), %rdi
callq 0x439d0
jmp 0x3668e
leaq 0x5b0(%rsp), %rdi
callq 0x439c0
leaq 0x5e0(%rsp), %rdi
callq 0x439d0
jmp 0x3669d
movl 0x634(%rsp), %eax
addq $0x638, %rsp            # imm = 0x638
retq
movq 0x598(%rsp), %rdi
callq 0x13970
nopw (%rax,%rax)