// File: tomfunkhouser[P]gaps/pkgs/R3Utils/R3Segmentation.cpp
// Function: gaps::R3Segmentation::DeleteClusters()
int R3Segmentation::
DeleteClusters(void)
{
  // Check if should delete clusters
  if (!allow_outlier_points) return 1;
  
  // Sort clusters
  clusters.Sort(CompareClusters);

  // Separate viable from nonviable ones
  RNArray<R3SegmentationCluster *> viable_clusters;
  RNArray<R3SegmentationCluster *> nonviable_clusters;
  for (int i = 0; i < clusters.NEntries(); i++) {
    R3SegmentationCluster *cluster = clusters.Kth(i);

    // Check min_clusters
    if ((min_clusters <= 0) || (i >= min_clusters)) {
      // Check cluster points
      if (min_cluster_points > 0) {
        if (cluster->points.NEntries() < min_cluster_points) {
          nonviable_clusters.Insert(cluster);
          continue;
        }
      }

      // Check cluster area
      if (min_cluster_area > 0) {
        if (cluster->area < min_cluster_area) {
          nonviable_clusters.Insert(cluster);
          continue;
        }
      }

      // Check cluster coverage
      if (min_cluster_coverage > 0) {
        if (cluster->Coverage() < min_cluster_coverage) {
          nonviable_clusters.Insert(cluster);
          continue;
        }
      }

      // Check max_clusters
      if (max_clusters > 0) {
        if (viable_clusters.NEntries() >= max_clusters) {
          nonviable_clusters.Insert(cluster);
          continue;
        }
      }
    }
    
    // R3SegmentationCluster is viable
    cluster->segmentation = this;
    cluster->segmentation_index = viable_clusters.NEntries();    
    viable_clusters.Insert(cluster);
  }

  // Delete nonviable clusters
  for (int i = 0; i < nonviable_clusters.NEntries(); i++) {
    R3SegmentationCluster *cluster = nonviable_clusters.Kth(i);
    delete cluster;
  }

  // Replace clusters with viable ones
  clusters = viable_clusters;

  // Return success
  return 1;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpl $0x0, 0xd4(%rax)
jne 0x44585
movl $0x1, 0x94(%rsp)
jmp 0x4487e
movq 0x38(%rsp), %rdi
addq $0x18, %rdi
leaq -0xc5(%rip), %rsi       # 0x444d0
callq 0x173cc0
leaq 0x78(%rsp), %rdi
callq 0x47650
leaq 0x68(%rsp), %rdi
callq 0x47650
jmp 0x445b0
movl $0x0, 0x58(%rsp)
movq 0x38(%rsp), %rdi
movl 0x58(%rsp), %eax
movl %eax, 0x30(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movl %eax, 0x34(%rsp)
jmp 0x445d4
movl 0x30(%rsp), %eax
movl 0x34(%rsp), %ecx
cmpl %ecx, %eax
jge 0x447bc
movq 0x38(%rsp), %rdi
addq $0x18, %rdi
movl 0x58(%rsp), %esi
callq 0x20270
movq %rax, 0x28(%rsp)
jmp 0x445fd
movq 0x38(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x50(%rsp)
cmpl $0x0, 0x30(%rax)
jle 0x44624
movq 0x38(%rsp), %rcx
movl 0x58(%rsp), %eax
cmpl 0x30(%rcx), %eax
jl 0x44769
movq 0x38(%rsp), %rax
cmpl $0x0, 0x38(%rax)
jle 0x44699
movq 0x50(%rsp), %rdi
addq $0x8, %rdi
callq 0x1ecf0
movl %eax, 0x24(%rsp)
jmp 0x44643
movl 0x24(%rsp), %eax
movq 0x38(%rsp), %rcx
cmpl 0x38(%rcx), %eax
jge 0x44697
movq 0x50(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x476c0
jmp 0x44662
jmp 0x447ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
jmp 0x44872
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x476a0
jmp 0x44872
jmp 0x44699
movq 0x38(%rsp), %rax
movsd 0x40(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x446e1
movq 0x38(%rsp), %rax
movq 0x50(%rsp), %rcx
movsd 0xe8(%rcx), %xmm1
movsd 0x40(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x446df
movq 0x50(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x476c0
jmp 0x446da
jmp 0x447ac
jmp 0x446e1
movq 0x38(%rsp), %rax
movsd 0x48(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x44729
movq 0x50(%rsp), %rdi
callq 0x3efe0
movq 0x38(%rsp), %rax
movaps %xmm0, %xmm1
movsd 0x48(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x44727
movq 0x50(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x476c0
jmp 0x44722
jmp 0x447ac
jmp 0x44729
movq 0x38(%rsp), %rax
cmpl $0x0, 0x34(%rax)
jle 0x44767
leaq 0x78(%rsp), %rdi
callq 0x1ecf0
movl %eax, 0x20(%rsp)
jmp 0x44744
movl 0x20(%rsp), %eax
movq 0x38(%rsp), %rcx
cmpl 0x34(%rcx), %eax
jl 0x44765
movq 0x50(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x476c0
jmp 0x44763
jmp 0x447ac
jmp 0x44767
jmp 0x44769
movq 0x38(%rsp), %rcx
movq 0x50(%rsp), %rax
movq %rcx, 0x130(%rax)
leaq 0x78(%rsp), %rdi
callq 0x1ecf0
movl %eax, 0x1c(%rsp)
jmp 0x4478a
movl 0x1c(%rsp), %ecx
movq 0x50(%rsp), %rax
movl %ecx, 0x138(%rax)
movq 0x50(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x476c0
jmp 0x447aa
jmp 0x447ac
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x445b8
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0x14(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x1ecf0
movl %eax, 0x18(%rsp)
jmp 0x447dc
movl 0x14(%rsp), %eax
movl 0x18(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4483c
movl 0x4c(%rsp), %esi
leaq 0x68(%rsp), %rdi
callq 0x20270
movq %rax, 0x8(%rsp)
jmp 0x447fd
movq 0x8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x4482d
movq (%rsp), %rdi
callq 0x3ee60
movq (%rsp), %rdi
movl $0x140, %esi            # imm = 0x140
callq 0x16750
jmp 0x4482f
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x447c4
movq 0x38(%rsp), %rdi
addq $0x18, %rdi
leaq 0x78(%rsp), %rsi
callq 0x47d90
jmp 0x44851
movl $0x1, 0x94(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x476a0
leaq 0x78(%rsp), %rdi
callq 0x476a0
jmp 0x4487e
leaq 0x78(%rsp), %rdi
callq 0x476a0
jmp 0x4488d
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
movq 0x60(%rsp), %rdi
callq 0x16ca0
nopw (%rax,%rax)