// File: tomfunkhouser[P]gaps/pkgs/R3Utils/R3Segmentation.cpp
// Function: gaps::R3Segmentation::CreateClusters(int)
int R3Segmentation::
CreateClusters(int primitive_type)
{
  // Print debug message
  RNTime step_time;
  step_time.Read();
  if (print_progress) {
    printf("      SA %.3f %d\n", step_time.Elapsed(), points.NEntries());
    step_time.Read();
  }

  // Create clusters
  if (initialize_hierarchically) {
    if (!CreateSingletonClusters(primitive_type)) return 0;
    if (!MergeClusters()) return 0;
  }
  else {
    if (!CreateRegionGrowingClusters(primitive_type)) return 0;
  }

  // Check clusters
  if (clusters.IsEmpty()) return 0;

  // Print debug message
  if (print_progress) {
    printf("      SB %.3f %d %d %g\n", step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
    step_time.Read();
  }

  // Iteratively update clusters
  for (int i = 0; i < max_refinement_iterations; i++) {
    // Reassign points to clusters
    if (!ReassignClusters()) return 0;

    // Print debug message
    if (print_progress) {
      printf("      SC %d : %.3f %d %d %g\n", i, step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
      step_time.Read();
    }

    // Create clusters
    if (!allow_outlier_points) {
      if (!CreateRegionGrowingClusters(primitive_type)) return 0;
    }

    // Print debug message
    if (print_progress) {
      printf("      SD %d : %.3f %d %d %g\n", i, step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
      step_time.Read();
    }

    // Merge clusters
    if (!MergeClusters()) return 0;

    // Print debug message
    if (print_progress) {
      printf("      SE %d : %.3f %d %d %g\n", i, step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
      step_time.Read();
    }

    // Refine boundaries
    if (!RefineBoundaries()) return 0;

    // Print debug message
    if (print_progress) {
      printf("      SF %d : %.3f %d %d %g\n", i, step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
      step_time.Read();
    }
    
    // Delete clusters
    if (!DeleteClusters()) return 0;

    // Print debug message
    if (print_progress) {
      printf("      SG %d : %.3f %d %d %g\n", i, step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
      step_time.Read();
    }
  }

  // Split clusters
  // if (!SplitClusters()) return 0;

  // Print debug message
  if (print_progress) {
    printf("      SH %.3f %d %d %g\n", step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
    step_time.Read();
  }

  // Refine boundaries
  if (!RefineBoundaries()) return 0;

  // Print debug message
  if (print_progress) {
    printf("      SI %.3f %d %d %g\n", step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
    step_time.Read();
  }

  // Delete clusters
  if (!DeleteClusters()) return 0;

  // Print debug message
  if (print_progress) {
    printf("      SJ %.3f %d %d %g\n", step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
    step_time.Read();
  }

  // Sort clusters
  clusters.Sort(CompareClusters);

  // Merge small clusters
  if (!MergeSmallClusters()) return 0;

  // Print debug message
  if (print_progress) {
    printf("      SK %.3f %d %d %g\n", step_time.Elapsed(), clusters.NEntries(), NUnclusteredPoints(), Affinity());
    step_time.Read();
  }
  // Return success
  return 1;
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0xf8(%rsp)
movl %esi, 0xf4(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0xd0(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x172a30
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x45f4a
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0xc8(%rsp)
callq 0x1ecf0
movsd 0xc8(%rsp), %xmm0
movl %eax, %esi
leaq 0x1b83df(%rip), %rdi    # 0x1fe315
movb $0x1, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xd0(%rax)
je 0x45fa8
movq 0xd0(%rsp), %rdi
movl 0xf4(%rsp), %esi
callq 0x43c30
cmpl $0x0, %eax
jne 0x45f84
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rdi
callq 0x448a0
cmpl $0x0, %eax
jne 0x45fa6
movl $0x0, 0x104(%rsp)
jmp 0x4674b
jmp 0x45fd3
movq 0xd0(%rsp), %rdi
movl 0xf4(%rsp), %esi
callq 0x43dd0
cmpl $0x0, %eax
jne 0x45fd1
movl $0x0, 0x104(%rsp)
jmp 0x4674b
jmp 0x45fd3
movq 0xd0(%rsp), %rdi
addq $0x18, %rdi
callq 0x3b4b0
cmpl $0x0, %eax
je 0x45ff9
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x46092
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0xc0(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0xb8(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0xbc(%rsp)
callq 0x42860
movl 0xb8(%rsp), %esi
movl 0xbc(%rsp), %edx
movaps %xmm0, %xmm1
movsd 0xc0(%rsp), %xmm0
leaq 0x1b82a9(%rip), %rdi    # 0x1fe327
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movl $0x0, 0xdc(%rsp)
movq 0xd0(%rsp), %rcx
movl 0xdc(%rsp), %eax
cmpl 0xb8(%rcx), %eax
jge 0x464b8
movq 0xd0(%rsp), %rdi
callq 0x441f0
cmpl $0x0, %eax
jne 0x460da
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x46188
movl 0xdc(%rsp), %eax
movl %eax, 0xa4(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0xb0(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0xa8(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0xac(%rsp)
callq 0x42860
movl 0xa4(%rsp), %esi
movl 0xa8(%rsp), %edx
movl 0xac(%rsp), %ecx
movaps %xmm0, %xmm1
movsd 0xb0(%rsp), %xmm0
leaq 0x1b81cb(%rip), %rdi    # 0x1fe33f
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xd4(%rax)
jne 0x461c4
movq 0xd0(%rsp), %rdi
movl 0xf4(%rsp), %esi
callq 0x43dd0
cmpl $0x0, %eax
jne 0x461c2
movl $0x0, 0x104(%rsp)
jmp 0x4674b
jmp 0x461c4
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x46272
movl 0xdc(%rsp), %eax
movl %eax, 0x8c(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x98(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x90(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x94(%rsp)
callq 0x42860
movl 0x8c(%rsp), %esi
movl 0x90(%rsp), %edx
movl 0x94(%rsp), %ecx
movaps %xmm0, %xmm1
movsd 0x98(%rsp), %xmm0
leaq 0x1b80fe(%rip), %rdi    # 0x1fe35c
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rdi
callq 0x448a0
cmpl $0x0, %eax
jne 0x46294
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x46330
movl 0xdc(%rsp), %eax
movl %eax, 0x74(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x80(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x78(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x7c(%rsp)
callq 0x42860
movl 0x74(%rsp), %esi
movl 0x78(%rsp), %edx
movl 0x7c(%rsp), %ecx
movaps %xmm0, %xmm1
movsd 0x80(%rsp), %xmm0
leaq 0x1b805d(%rip), %rdi    # 0x1fe379
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rdi
callq 0x45c40
cmpl $0x0, %eax
jne 0x46352
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x463e8
movl 0xdc(%rsp), %eax
movl %eax, 0x5c(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x68(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x60(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x64(%rsp)
callq 0x42860
movl 0x5c(%rsp), %esi
movl 0x60(%rsp), %edx
movl 0x64(%rsp), %ecx
movaps %xmm0, %xmm1
movsd 0x68(%rsp), %xmm0
leaq 0x1b7fc2(%rip), %rdi    # 0x1fe396
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rdi
callq 0x44550
cmpl $0x0, %eax
jne 0x4640a
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x464a0
movl 0xdc(%rsp), %eax
movl %eax, 0x44(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x50(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x48(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x4c(%rsp)
callq 0x42860
movl 0x44(%rsp), %esi
movl 0x48(%rsp), %edx
movl 0x4c(%rsp), %ecx
movaps %xmm0, %xmm1
movsd 0x50(%rsp), %xmm0
leaq 0x1b7f27(%rip), %rdi    # 0x1fe3b3
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
jmp 0x464a2
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x4609d
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x4653b
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x38(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x30(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x34(%rsp)
callq 0x42860
movl 0x30(%rsp), %esi
movl 0x34(%rsp), %edx
movaps %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
leaq 0x1b7ea9(%rip), %rdi    # 0x1fe3d0
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rdi
callq 0x45c40
cmpl $0x0, %eax
jne 0x4655d
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x465e0
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x28(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x20(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x24(%rsp)
callq 0x42860
movl 0x20(%rsp), %esi
movl 0x24(%rsp), %edx
movaps %xmm0, %xmm1
movsd 0x28(%rsp), %xmm0
leaq 0x1b7e1c(%rip), %rdi    # 0x1fe3e8
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rdi
callq 0x44550
cmpl $0x0, %eax
jne 0x46602
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x46685
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x18(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, 0x10(%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x14(%rsp)
callq 0x42860
movl 0x10(%rsp), %esi
movl 0x14(%rsp), %edx
movaps %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
leaq 0x1b7d8f(%rip), %rdi    # 0x1fe400
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movq 0xd0(%rsp), %rdi
addq $0x18, %rdi
leaq -0x21c8(%rip), %rsi     # 0x444d0
callq 0x173cc0
movq 0xd0(%rsp), %rdi
callq 0x458b0
cmpl $0x0, %eax
jne 0x466bf
movl $0x0, 0x104(%rsp)
jmp 0x4674b
movq 0xd0(%rsp), %rax
cmpl $0x0, 0xdc(%rax)
je 0x46740
leaq 0xe0(%rsp), %rdi
callq 0x172af0
movq 0xd0(%rsp), %rdi
movsd %xmm0, 0x8(%rsp)
addq $0x18, %rdi
callq 0x1ecf0
movq 0xd0(%rsp), %rdi
movl %eax, (%rsp)
callq 0x428f0
movq 0xd0(%rsp), %rdi
movl %eax, 0x4(%rsp)
callq 0x42860
movl (%rsp), %esi
movl 0x4(%rsp), %edx
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
leaq 0x1b7cec(%rip), %rdi    # 0x1fe418
movb $0x2, %al
callq 0x16090
leaq 0xe0(%rsp), %rdi
callq 0x1ec90
movl $0x1, 0x104(%rsp)
movl 0x104(%rsp), %eax
addq $0x108, %rsp            # imm = 0x108
retq
nopw (%rax,%rax)