// File: tomfunkhouser[P]gaps/pkgs/R3Utils/R3Segmentation.cpp
// Function: gaps::R3Segmentation::RefineBoundaries()
int R3Segmentation::
RefineBoundaries(void)
{
  // Check if should refine boundaries
  if (!refine_boundaries) return 1;

  // Iteratively refine boundaries
  for (int iter = 0; iter < 1000; iter++) {
    RNBoolean done = TRUE;
    for (int i0 = 0; i0 < points.NEntries(); i0++) {
      R3SegmentationPoint *point0 = points.Kth(i0);
      if (point0->neighbors.NEntries() < 3) continue;
      R3SegmentationCluster *cluster0 = point0->cluster;
      if (!cluster0) continue;
      int i1 = RNRandomScalar() * point0->neighbors.NEntries();
      R3SegmentationPoint *point1 = point0->neighbors.Kth(i1);
      R3SegmentationCluster *cluster1 = point1->cluster;
      if (!cluster1) continue;
      if (cluster0 == cluster1) continue;
      int count = 0;
      for (int i2 = 0; i2 < point0->neighbors.NEntries(); i2++) {
        R3SegmentationPoint *point2 = point0->neighbors.Kth(i2);
        R3SegmentationCluster *cluster2 = point2->cluster;
        if (!cluster2) continue;
        if (cluster2 == cluster1) count++;
      }
      if (count > point0->neighbors.NEntries()/2) {
        cluster0->RemovePoint(point0);
        cluster1->InsertPoint(point0, point0->cluster_affinity);
        done = FALSE;
      }
    }
    if (done) break;
  }

  // Return success
  return 1;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x78(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpl $0x0, 0xd8(%rax)
jne 0x45c6f
movl $0x1, 0x84(%rsp)
jmp 0x45ea0
movl $0x0, 0x74(%rsp)
cmpl $0x3e8, 0x74(%rsp)      # imm = 0x3E8
jge 0x45e95
movl $0x1, 0x70(%rsp)
movl $0x0, 0x6c(%rsp)
movq 0x20(%rsp), %rdi
movl 0x6c(%rsp), %eax
movl %eax, 0x1c(%rsp)
callq 0x1ecf0
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x45e7a
movq 0x20(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x1f6a0
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rdi
addq $0xb0, %rdi
callq 0x1ecf0
cmpl $0x3, %eax
jge 0x45ce3
jmp 0x45e6a
movq 0x60(%rsp), %rax
movq 0xc0(%rax), %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x45d01
jmp 0x45e6a
callq 0x176430
movsd %xmm0, 0x10(%rsp)
movq 0x60(%rsp), %rdi
addq $0xb0, %rdi
callq 0x1ecf0
movsd 0x10(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x54(%rsp)
movq 0x60(%rsp), %rdi
addq $0xb0, %rdi
movl 0x54(%rsp), %esi
callq 0x1f6a0
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movq 0xc0(%rax), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
jne 0x45d6b
jmp 0x45e6a
movq 0x58(%rsp), %rax
cmpq 0x40(%rsp), %rax
jne 0x45d7c
jmp 0x45e6a
movl $0x0, 0x3c(%rsp)
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x60(%rsp), %rdi
addq $0xb0, %rdi
callq 0x1ecf0
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x45e0a
movq 0x60(%rsp), %rdi
addq $0xb0, %rdi
movl 0x38(%rsp), %esi
callq 0x1f6a0
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq 0xc0(%rax), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0x45de4
jmp 0x45dfd
movq 0x28(%rsp), %rax
cmpq 0x40(%rsp), %rax
jne 0x45dfb
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x45dfd
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x45d8c
movl 0x3c(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0x60(%rsp), %rdi
addq $0xb0, %rdi
callq 0x1ecf0
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
jle 0x45e68
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x3e080
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x60(%rsp), %rax
movsd 0xc8(%rax), %xmm0
callq 0x3ec40
movl $0x0, 0x70(%rsp)
jmp 0x45e6a
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x45c95
cmpl $0x0, 0x70(%rsp)
je 0x45e83
jmp 0x45e95
jmp 0x45e85
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x45c77
movl $0x1, 0x84(%rsp)
movl 0x84(%rsp), %eax
addq $0x88, %rsp
retq
nop