// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelScene.cpp
// Function: gaps::R3SurfelScene::MergeObject(gaps::R3SurfelObject*, gaps::R3SurfelObject*)
void R3SurfelScene::
MergeObject(R3SurfelObject *dst_object, R3SurfelObject *src_object)
{
  // Just checking
  assert(dst_object && src_object);
  assert(dst_object->scene == this);
  assert(dst_object->scene_index >= 0);
  assert(src_object->scene == this);
  assert(src_object->scene_index >= 0);

  // Move all nodes from src_object into dst_object
  while (src_object->NNodes() > 0) {
    R3SurfelNode *node = src_object->Node(src_object->NNodes()-1);
    src_object->RemoveNode(node);
    dst_object->InsertNode(node);
  }

  // Move all parts from src_object into dst_object
  while (src_object->NParts() > 0) {
    R3SurfelObject *part = src_object->Part(src_object->NParts()-1);
    RemoveObject(part);
    InsertObject(part, dst_object);
  }

  // Move all object properties from src_object into dst_object
  while (src_object->NObjectProperties() > 0) {
    R3SurfelObjectProperty *property = src_object->ObjectProperty(src_object->NObjectProperties()-1);
    src_object->UpdateBeforeRemoveObjectProperty(property);
    property->object = dst_object;
    dst_object->UpdateAfterInsertObjectProperty(property);
  }

  // Move all object relationships from src_object into dst_object
  while (src_object->NObjectRelationships() > 0) {
    R3SurfelObjectRelationship *relationship = src_object->ObjectRelationship(src_object->NObjectRelationships()-1);
    src_object->UpdateBeforeRemoveObjectRelationship(relationship);
    for (int i = 0; i < relationship->objects.NEntries(); i++) {
      if (relationship->objects.Kth(i) == src_object) {
        RNArrayEntry *entry = relationship->objects.KthEntry(i);
        relationship->objects.EntryContents(entry) = dst_object;
        break;
      }
    }
    dst_object->UpdateAfterInsertObjectRelationship(relationship);
  }

  // Move all label assignments from src_object into dst_object
  while (src_object->NLabelAssignments() > 0) {
    R3SurfelLabelAssignment *assignment = src_object->LabelAssignment(src_object->NLabelAssignments()-1);
    src_object->UpdateBeforeRemoveLabelAssignment(assignment);
    assignment->object = dst_object;
    dst_object->UpdateAfterInsertLabelAssignment(assignment);
  }

  // Remove src_object
  RemoveObject(src_object);

  // Delete src_object
  delete src_object;

  // Mark scene as dirty
  flags.Add(R3_SURFEL_SCENE_DIRTY_FLAG);
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0xa0(%rsp)
movq %rsi, 0x98(%rsp)
movq %rdx, 0x90(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x90(%rsp), %rdi
callq 0x18660
cmpl $0x0, %eax
jle 0x1e26b
movq 0x90(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x90(%rsp), %rdi
callq 0x18660
movq 0x40(%rsp), %rdi
movl %eax, %esi
subl $0x1, %esi
callq 0x18680
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0x191d0
movq 0x98(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0x1ac10
jmp 0x1e1fc
jmp 0x1e26d
movq 0x90(%rsp), %rdi
callq 0x1bb10
cmpl $0x0, %eax
jle 0x1e2e0
movq 0x90(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x90(%rsp), %rdi
callq 0x1bb10
movq 0x38(%rsp), %rdi
movl %eax, %esi
subl $0x1, %esi
callq 0x1bb30
movq 0x48(%rsp), %rdi
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rsi
movq (%rdi), %rax
callq *0x20(%rax)
movq 0x48(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x98(%rsp), %rdx
movq (%rdi), %rax
callq *0x18(%rax)
jmp 0x1e26d
jmp 0x1e2e2
movq 0x90(%rsp), %rdi
callq 0x1ba20
cmpl $0x0, %eax
jle 0x1e359
movq 0x90(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x90(%rsp), %rdi
callq 0x1ba20
movq 0x30(%rsp), %rdi
movl %eax, %esi
subl $0x1, %esi
callq 0x1ba40
movq %rax, 0x78(%rsp)
movq 0x90(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x1b410
movq 0x98(%rsp), %rcx
movq 0x78(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x98(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x1b3e0
jmp 0x1e2e2
jmp 0x1e35b
movq 0x90(%rsp), %rdi
callq 0x1ba70
cmpl $0x0, %eax
jle 0x1e45f
movq 0x90(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x90(%rsp), %rdi
callq 0x1ba70
movq 0x28(%rsp), %rdi
movl %eax, %esi
subl $0x1, %esi
callq 0x1ba90
movq %rax, 0x70(%rsp)
movq 0x90(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x1b470
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x70(%rsp), %rdi
addq $0x18, %rdi
callq 0x16d50
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x1e448
movq 0x70(%rsp), %rdi
addq $0x18, %rdi
movl 0x6c(%rsp), %esi
callq 0x18840
cmpq 0x90(%rsp), %rax
jne 0x1e436
movq 0x70(%rsp), %rdi
addq $0x18, %rdi
movl 0x6c(%rsp), %esi
callq 0x1c080
movq %rax, 0x60(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x70(%rsp), %rdi
addq $0x18, %rdi
movq 0x60(%rsp), %rsi
callq 0x30ac0
movq 0x18(%rsp), %rcx
movq %rcx, (%rax)
jmp 0x1e448
jmp 0x1e438
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x1e3b9
movq 0x98(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x1b440
jmp 0x1e35b
jmp 0x1e461
movq 0x90(%rsp), %rdi
callq 0x1bac0
cmpl $0x0, %eax
jle 0x1e4d8
movq 0x90(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x90(%rsp), %rdi
callq 0x1bac0
movq 0x10(%rsp), %rdi
movl %eax, %esi
subl $0x1, %esi
callq 0x1bae0
movq %rax, 0x58(%rsp)
movq 0x90(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x1b4f0
movq 0x98(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x98(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x1b4a0
jmp 0x1e461
movq 0x48(%rsp), %rdi
movq 0x90(%rsp), %rsi
movq (%rdi), %rax
callq *0x20(%rax)
movq 0x90(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x1e509
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x48(%rsp), %rax
addq $0x1e8, %rax            # imm = 0x1E8
movq %rax, (%rsp)
leaq 0x50(%rsp), %rdi
movl $0x1, %esi
callq 0x1b970
movq (%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x1c2d0
addq $0xa8, %rsp
retq
nopl (%rax)