// File: tomfunkhouser[P]gaps/pkgs/R3Utils/R3Segmentation.cpp
// Function: gaps::R3Segmentation::CreateRegionGrowingClusters(int)
int R3Segmentation::
CreateRegionGrowingClusters(int primitive_type)
{
  // Determine how many seed points to skip each iteration
  int skip = 1;
  if (allow_outlier_points) {
    if ((max_clusters > 0) && (points.NEntries()/(4*max_clusters) > skip))
      skip = points.NEntries()/(4*max_clusters);
    if ((min_cluster_points > 0) && ((min_cluster_points/4) > skip))
      skip = min_cluster_points/4;
    if ((min_clusters > 0) && (skip > points.NEntries()/min_clusters))
      skip = points.NEntries()/min_clusters;
  }

  // Search seed points
  int seed_index = 0;
  while (seed_index < points.NEntries()) {
    // Find next seed point
    R3SegmentationPoint *seed_point = NULL;
    while ((seed_index < points.NEntries()) && !seed_point) {
      R3SegmentationPoint *point = points.Kth(seed_index);
      if (!point->cluster) seed_point = point;
      seed_index += skip; 
    }

    // Check seed point
    if (!seed_point) break;

    // Create cluster
    R3SegmentationPrimitive primitive(primitive_type);
    primitive.Update(seed_point);
    R3SegmentationCluster *cluster = new R3SegmentationCluster(seed_point, primitive);
    if (!cluster->UpdatePoints(kdtree)) { delete cluster; continue; }
    if (!cluster->UpdateColor()) { delete cluster; continue; }
    if (!cluster->UpdateTimestamp()) { delete cluster; continue; }

    // Insert cluster
    cluster->segmentation = this;
    cluster->segmentation_index = clusters.NEntries();    
    clusters.Insert(cluster);
  } 

  // Return success
  return 1;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x150(%rsp)
movl %esi, 0x14c(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x60(%rsp)
movl $0x1, 0x148(%rsp)
cmpl $0x0, 0xd4(%rax)
je 0x43ee0
movq 0x60(%rsp), %rax
cmpl $0x0, 0x34(%rax)
jle 0x43e56
movq 0x60(%rsp), %rdi
callq 0x1ecf0
movq 0x60(%rsp), %rcx
movl 0x34(%rcx), %ecx
shll $0x2, %ecx
cltd
idivl %ecx
cmpl 0x148(%rsp), %eax
jle 0x43e56
movq 0x60(%rsp), %rdi
callq 0x1ecf0
movq 0x60(%rsp), %rcx
movl 0x34(%rcx), %ecx
shll $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x148(%rsp)
movq 0x60(%rsp), %rax
cmpl $0x0, 0x38(%rax)
jle 0x43e91
movq 0x60(%rsp), %rax
movl 0x38(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl 0x148(%rsp), %eax
jle 0x43e91
movq 0x60(%rsp), %rax
movl 0x38(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl %eax, 0x148(%rsp)
movq 0x60(%rsp), %rax
cmpl $0x0, 0x30(%rax)
jle 0x43ede
movq 0x60(%rsp), %rdi
movl 0x148(%rsp), %eax
movl %eax, 0x5c(%rsp)
callq 0x1ecf0
movq 0x60(%rsp), %rcx
cltd
idivl 0x30(%rcx)
movl %eax, %ecx
movl 0x5c(%rsp), %eax
cmpl %ecx, %eax
jle 0x43ede
movq 0x60(%rsp), %rdi
callq 0x1ecf0
movq 0x60(%rsp), %rcx
cltd
idivl 0x30(%rcx)
movl %eax, 0x148(%rsp)
jmp 0x43ee0
movl $0x0, 0x144(%rsp)
movq 0x60(%rsp), %rdi
movl 0x144(%rsp), %eax
movl %eax, 0x58(%rsp)
callq 0x1ecf0
movl %eax, %ecx
movl 0x58(%rsp), %eax
cmpl %ecx, %eax
jge 0x441d2
movq $0x0, 0x138(%rsp)
movq 0x60(%rsp), %rdi
movl 0x144(%rsp), %eax
movl %eax, 0x50(%rsp)
callq 0x1ecf0
movl 0x50(%rsp), %ecx
movl %eax, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, 0x57(%rsp)
jge 0x43f51
cmpq $0x0, 0x138(%rsp)
setne %al
xorb $-0x1, %al
movb %al, 0x57(%rsp)
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x43f5b
jmp 0x43fb0
movq 0x60(%rsp), %rdi
movl 0x144(%rsp), %esi
callq 0x1f6a0
movq %rax, 0x130(%rsp)
movq 0x130(%rsp), %rax
cmpq $0x0, 0xc0(%rax)
jne 0x43f96
movq 0x130(%rsp), %rax
movq %rax, 0x138(%rsp)
movl 0x148(%rsp), %eax
addl 0x144(%rsp), %eax
movl %eax, 0x144(%rsp)
jmp 0x43f1a
cmpq $0x0, 0x138(%rsp)
jne 0x43fc0
jmp 0x441d2
movl 0x14c(%rsp), %esi
leaq 0x88(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x3bfc0
movq 0x48(%rsp), %rdi
movq 0x138(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x3c1e0
jmp 0x43ff1
movl $0x140, %edi            # imm = 0x140
callq 0x16740
movq %rax, 0x40(%rsp)
jmp 0x44002
movq 0x40(%rsp), %rdi
movq 0x138(%rsp), %rsi
leaq 0x88(%rsp), %rdx
callq 0x3d420
jmp 0x4401e
movq 0x60(%rsp), %rax
movq 0x40(%rsp), %rcx
movq %rcx, 0x70(%rsp)
movq 0x70(%rsp), %rdi
movq 0x10(%rax), %rsi
callq 0x40020
movl %eax, 0x3c(%rsp)
jmp 0x44041
movl 0x3c(%rsp), %eax
cmpl $0x0, %eax
jne 0x440bb
movq 0x70(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x44073
movq 0x30(%rsp), %rdi
callq 0x3ee60
movq 0x30(%rsp), %rdi
movl $0x140, %esi            # imm = 0x140
callq 0x16750
movl $0x2, 0x6c(%rsp)
jmp 0x441a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x80(%rsp)
movl %eax, 0x7c(%rsp)
jmp 0x441c3
movq 0x40(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x80(%rsp)
movl %eax, 0x7c(%rsp)
movl $0x140, %esi            # imm = 0x140
callq 0x16750
jmp 0x441c3
movq 0x70(%rsp), %rdi
callq 0x40780
movl %eax, 0x2c(%rsp)
jmp 0x440cb
movl 0x2c(%rsp), %eax
cmpl $0x0, %eax
jne 0x4410a
movq 0x70(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x440fd
movq 0x20(%rsp), %rdi
callq 0x3ee60
movq 0x20(%rsp), %rdi
movl $0x140, %esi            # imm = 0x140
callq 0x16750
movl $0x2, 0x6c(%rsp)
jmp 0x441a2
movq 0x70(%rsp), %rdi
callq 0x40860
movl %eax, 0x1c(%rsp)
jmp 0x4411a
movl 0x1c(%rsp), %eax
cmpl $0x0, %eax
jne 0x44156
movq 0x70(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x4414c
movq 0x10(%rsp), %rdi
callq 0x3ee60
movq 0x10(%rsp), %rdi
movl $0x140, %esi            # imm = 0x140
callq 0x16750
movl $0x2, 0x6c(%rsp)
jmp 0x441a2
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq %rdi, 0x130(%rax)
addq $0x18, %rdi
callq 0x1ecf0
movl %eax, 0xc(%rsp)
jmp 0x44176
movq 0x60(%rsp), %rdi
movl 0xc(%rsp), %ecx
movq 0x70(%rsp), %rax
movl %ecx, 0x138(%rax)
addq $0x18, %rdi
movq 0x70(%rsp), %rsi
callq 0x476c0
jmp 0x4419a
movl $0x0, 0x6c(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x47670
movl 0x6c(%rsp), %eax
testl %eax, %eax
je 0x441be
jmp 0x441b9
jmp 0x43eeb
jmp 0x43eeb
leaq 0x88(%rsp), %rdi
callq 0x47670
jmp 0x441df
movl $0x1, %eax
addq $0x158, %rsp            # imm = 0x158
retq
movq 0x80(%rsp), %rdi
callq 0x16ca0
nopl (%rax)