// File: tomfunkhouser[P]gaps/pkgs/R3Utils/R3Segmentation.cpp
// Function: gaps::R3Segmentation::MergeSmallClusters()
int R3Segmentation::
MergeSmallClusters(void)
{
  // Find small clusters
  RNArray<R3SegmentationCluster *> small_clusters;
  for (int i = 0; i < clusters.NEntries(); i++) {
    R3SegmentationCluster *cluster = clusters.Kth(i);
    assert(!cluster->parent);
    if (cluster->points.NEntries() >= min_cluster_points) continue;
    small_clusters.Insert(cluster);
  }

  // Check small clusters
  if (small_clusters.NEntries() < 2) return 1;

  // Merge n-1 small clusters into first one
  R3SegmentationCluster *cluster0 = small_clusters.Kth(0);
  for (int i = 1; i < small_clusters.NEntries(); i++) {
    R3SegmentationCluster *cluster = small_clusters.Kth(i);
    if (cluster == cluster0) continue;
    cluster0->InsertChild(cluster);
    assert(cluster->parent == cluster0);
    assert(cluster0->points.NEntries() > 0);
    assert(cluster->points.NEntries() == 0);
  }

  // Rebuild list of clusters
  RNArray<R3SegmentationCluster *> all_clusters = clusters;
  clusters.Empty();
  for (int i = 0; i < all_clusters.NEntries(); i++) {
    R3SegmentationCluster *cluster = all_clusters.Kth(i);
    if (!cluster->parent) {
      assert((cluster == cluster0) || (cluster->points.NEntries() >= min_cluster_points));
      cluster->segmentation = this;
      cluster->segmentation_index = clusters.NEntries();    
      clusters.Insert(cluster);
    }
    else {
      assert(cluster->points.NEntries() == 0);
      cluster->parent->RemoveChild(cluster);
      delete cluster;
    }
  }

  // Return success
  return 1;
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x47650
movl $0x0, 0xb4(%rsp)
movq 0x50(%rsp), %rdi
movl 0xb4(%rsp), %eax
movl %eax, 0x48(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movl %eax, 0x4c(%rsp)
jmp 0x45903
movl 0x48(%rsp), %eax
movl 0x4c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x459ab
movq 0x50(%rsp), %rdi
addq $0x18, %rdi
movl 0xb4(%rsp), %esi
callq 0x20270
movq %rax, 0x40(%rsp)
jmp 0x4592f
movq 0x40(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rdi
addq $0x8, %rdi
callq 0x1ecf0
movl %eax, 0x3c(%rsp)
jmp 0x45953
movl 0x3c(%rsp), %eax
movq 0x50(%rsp), %rcx
cmpl 0x38(%rcx), %eax
jl 0x4597c
jmp 0x45995
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa8(%rsp)
movl %eax, 0xa4(%rsp)
jmp 0x45c0d
movq 0x98(%rsp), %rsi
leaq 0xb8(%rsp), %rdi
callq 0x476c0
jmp 0x45993
jmp 0x45995
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x458e4
leaq 0xb8(%rsp), %rdi
callq 0x1ecf0
movl %eax, 0x38(%rsp)
jmp 0x459be
movl 0x38(%rsp), %eax
cmpl $0x2, %eax
jge 0x459e2
movl $0x1, 0xd4(%rsp)
movl $0x1, 0x94(%rsp)
jmp 0x45bf1
leaq 0xb8(%rsp), %rdi
xorl %esi, %esi
callq 0x20270
movq %rax, 0x30(%rsp)
jmp 0x459f8
movq 0x30(%rsp), %rax
movq %rax, 0x88(%rsp)
movl $0x1, 0x84(%rsp)
movl 0x84(%rsp), %eax
movl %eax, 0x28(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x1ecf0
movl %eax, 0x2c(%rsp)
jmp 0x45a2e
movl 0x28(%rsp), %eax
movl 0x2c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x45a9c
movl 0x84(%rsp), %esi
leaq 0xb8(%rsp), %rdi
callq 0x20270
movq %rax, 0x20(%rsp)
jmp 0x45a55
movq 0x20(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rax
cmpq 0x88(%rsp), %rax
jne 0x45a70
jmp 0x45a86
movq 0x88(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x3f6b0
jmp 0x45a84
jmp 0x45a86
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x45a10
movq 0x50(%rsp), %rsi
addq $0x18, %rsi
leaq 0x68(%rsp), %rdi
callq 0x47d60
jmp 0x45ab1
movq 0x50(%rsp), %rdi
addq $0x18, %rdi
xorl %esi, %esi
callq 0x173a50
jmp 0x45ac3
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
movl %eax, 0x18(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x1ecf0
movl %eax, 0x1c(%rsp)
jmp 0x45ae3
movl 0x18(%rsp), %eax
movl 0x1c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x45bd1
movl 0x64(%rsp), %esi
leaq 0x68(%rsp), %rdi
callq 0x20270
movq %rax, 0x10(%rsp)
jmp 0x45b08
movq 0x10(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x45b87
movq 0x50(%rsp), %rdi
movq 0x58(%rsp), %rax
movq %rdi, 0x130(%rax)
addq $0x18, %rdi
callq 0x1ecf0
movl %eax, 0xc(%rsp)
jmp 0x45b3e
movq 0x50(%rsp), %rdi
movl 0xc(%rsp), %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x138(%rax)
addq $0x18, %rdi
movq 0x58(%rsp), %rsi
callq 0x476c0
jmp 0x45b62
jmp 0x45bbf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa8(%rsp)
movl %eax, 0xa4(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x476a0
jmp 0x45c0d
movq 0x58(%rsp), %rsi
movq 0x18(%rsi), %rdi
callq 0x3fe30
jmp 0x45b97
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x45bbd
movq (%rsp), %rdi
callq 0x3ee60
movq (%rsp), %rdi
movl $0x140, %esi            # imm = 0x140
callq 0x16750
jmp 0x45bbf
jmp 0x45bc1
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x45acb
movl $0x1, 0xd4(%rsp)
movl $0x1, 0x94(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x476a0
leaq 0xb8(%rsp), %rdi
callq 0x476a0
movl 0xd4(%rsp), %eax
addq $0xd8, %rsp
retq
leaq 0xb8(%rsp), %rdi
callq 0x476a0
movq 0xa8(%rsp), %rdi
callq 0x16ca0
nopw (%rax,%rax)