// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Utils/R3Segmentation.cpp
// Function: gaps::R3Segmentation::CreateNeighbors(int, double, double, double, double, double, double, double, int)
int R3Segmentation::
CreateNeighbors(
  int max_neighbor_count,
  double max_neighbor_distance,
  double max_neighbor_primitive_distance,
  double max_neighbor_normal_angle,
  double max_neighbor_color_difference,
  double max_neighbor_distance_factor,
  double max_neighbor_timestamp_difference,
  double max_neighbor_category_difference,
  RNBoolean partition_identifiers)
{
  // Create kdtree of points
  R3SegmentationPoint tmp; int position_offset = (unsigned char *) &(tmp.position) - (unsigned char *) &tmp;
  kdtree = new R3Kdtree<R3SegmentationPoint *>(points, position_offset);
  if (!kdtree) {
    RNFail("Unable to create kdtree\n");
    return 0;
  }
  
  // Create arrays of neighbor points
  for (int i = 0; i < points.NEntries(); i++) {
    R3SegmentationPoint *point = points.Kth(i);

    // Refine maximum distance for this point
    RNScalar max_d = max_neighbor_distance;
    if ((max_neighbor_distance_factor > 0) && (point->radius1 > 0)) 
      max_d = max_neighbor_distance_factor * point->radius1;
    if (max_d == 0) max_d = 10 * point->radius1;
    if (max_d == 0) max_d = 1;

    // Create neighbors
    double min_affinity = 0;
    RNArray<R3SegmentationPoint *> neighbors;
    if (kdtree->FindClosest(point, 0, max_d, max_neighbor_count, neighbors)) {
      for (int j = 0; j < neighbors.NEntries(); j++) {
        R3SegmentationPoint *neighbor = neighbors.Kth(j);
        if (neighbor == point) continue;
        
        // Check identifier
        if (partition_identifiers) {
          if (point->identifier != neighbor->identifier) continue;
        }

        // Compute affinity
        RNScalar affinity = R3SegmentationPointAffinity(point, neighbor,
          max_d, max_neighbor_primitive_distance,
          max_neighbor_normal_angle, max_neighbor_color_difference,
          max_neighbor_timestamp_difference,
          max_neighbor_category_difference, min_affinity);
        if (affinity <= min_affinity) continue;
        
        // Insert neighbor
        if ((max_neighbor_count > 0) &&
            (neighbors.NEntries() - j > max_neighbor_count - point->neighbors.NEntries())) {
          // Find slot for neighbor in list sorted by affinity
          int slot = point->neighbors.NEntries();
          while (slot > 0) {
            RNScalar s_affinity = point->neighbors[slot-1]->cluster_affinity;
            if (s_affinity > affinity) break;
            slot--;
          }
          if (slot < max_neighbor_count) {
            neighbor->cluster_affinity = affinity;
            point->neighbors.InsertKth(neighbor, slot);
            point->neighbors.Truncate(max_neighbor_count);
          }
          if (point->neighbors.NEntries() == max_neighbor_count) {
            min_affinity = point->neighbors[point->neighbors.NEntries()-1]->cluster_affinity;
          }
        }
        else {
          // Insert neighbor at end of unconstrained list
          point->neighbors.Insert(neighbor);
        }
      }
    }
  }

  // Reset cluster affinities
  for (int i = 0; i < points.NEntries(); i++) {
    R3SegmentationPoint *point = points.Kth(i);
    point->cluster_affinity = 0;
  }
  
  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1f8, %rsp            # imm = 0x1F8
movl %edx, 0x34(%rsp)
movsd %xmm6, 0x68(%rsp)
movsd %xmm5, 0xb8(%rsp)
movsd %xmm4, 0x48(%rsp)
movsd %xmm3, 0x98(%rsp)
movsd %xmm2, 0x58(%rsp)
movapd %xmm1, 0x70(%rsp)
movsd %xmm0, 0x50(%rsp)
movl %esi, %ebp
movq %rdi, %r15
leaq 0x118(%rsp), %rdi
callq 0x28e2c
movl $0x60, %edi
callq 0x15610
movq %rax, %r14
movq %rax, %rdi
movq %r15, %rsi
movl $0x8, %edx
callq 0x1aa8e
movq %r14, 0x10(%r15)
cmpl $0x0, 0xc(%r15)
jle 0x2c82c
leaq 0xe7974(%rip), %rax     # 0x113ba8
movsd (%rax), %xmm0
movsd %xmm0, 0x90(%rsp)
movl %ebp, %eax
movq %rax, 0x88(%rsp)
movapd 0x70(%rsp), %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
movapd %xmm0, 0xe0(%rsp)
xorl %ecx, %ecx
leaq 0x38(%rsp), %r14
movq %r15, 0xa0(%rsp)
movsd 0x48(%rsp), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movq (%r15), %rax
movq (%rax,%rcx,8), %r13
movsd 0x50(%rsp), %xmm2
jbe 0x2c2a6
movsd 0x50(%r13), %xmm0
ucomisd %xmm1, %xmm0
movsd 0x50(%rsp), %xmm2
jbe 0x2c2a6
mulsd 0x48(%rsp), %xmm0
movapd %xmm0, %xmm2
movapd %xmm2, 0x10(%rsp)
ucomisd %xmm1, %xmm2
jne 0x2c2c8
jp 0x2c2c8
movsd 0x50(%r13), %xmm0
mulsd 0xddfd6(%rip), %xmm0    # 0x10a298
movapd %xmm0, 0x10(%rsp)
movq %rcx, 0xa8(%rsp)
movq %r14, %rdi
callq 0xc352c
movapd 0x10(%rsp), %xmm3
movapd %xmm3, %xmm2
cmpeqsd 0xdcd6d(%rip), %xmm2    # 0x109058
movapd %xmm2, %xmm0
movsd 0xdcd59(%rip), %xmm1    # 0x109050
andpd %xmm1, %xmm0
andnpd %xmm3, %xmm2
orpd %xmm0, %xmm2
movq 0x10(%r15), %rdi
movq $0x0, (%rsp)
xorpd %xmm0, %xmm0
movq %r13, %rsi
movapd %xmm2, 0xd0(%rsp)
movapd %xmm2, %xmm1
movl %ebp, %ebx
movl %ebp, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
movq %r14, %r9
callq 0x2efec
testl %eax, %eax
je 0x2c7dd
cmpl $0x0, 0x44(%rsp)
jle 0x2c7dd
movapd 0xd0(%rsp), %xmm0
mulsd %xmm0, %xmm0
movsd %xmm0, 0xb0(%rsp)
leaq 0x8(%r13), %rax
movq %rax, 0x28(%rsp)
leaq 0x20(%r13), %rax
movq %rax, 0x60(%rsp)
leaq 0xb0(%r13), %r12
xorpd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
xorl %ebp, %ebp
movq 0x38(%rsp), %rax
movq (%rax,%rbp,8), %r14
cmpq %r13, %r14
je 0x2c778
cmpl $0x0, 0x34(%rsp)
je 0x2c3af
movl 0xa8(%r13), %eax
cmpl 0xa8(%r14), %eax
jne 0x2c778
movsd 0x68(%rsp), %xmm0
ucomisd 0xdcc9b(%rip), %xmm0    # 0x109058
movsd 0xdcc8b(%rip), %xmm0    # 0x109050
movapd %xmm0, 0x10(%rsp)
jbe 0x2c3ef
movl 0x90(%r13), %eax
movsd 0xdcc74(%rip), %xmm0    # 0x109050
movapd %xmm0, 0x10(%rsp)
cmpl 0x90(%r14), %eax
jne 0x2c554
movsd 0xb8(%rsp), %xmm1
ucomisd 0xdcc58(%rip), %xmm1    # 0x109058
jbe 0x2c454
movsd 0x68(%r13), %xmm0
subsd 0x68(%r14), %xmm0
andpd 0xdd15a(%rip), %xmm0    # 0x109570
xorpd %xmm3, %xmm3
ucomisd %xmm1, %xmm0
ja 0x2c719
divsd %xmm1, %xmm0
movsd 0xdcc20(%rip), %xmm1    # 0x109050
subsd %xmm0, %xmm1
movapd 0x10(%rsp), %xmm2
mulsd %xmm1, %xmm2
movsd 0x8(%rsp), %xmm0
movapd %xmm2, 0x10(%rsp)
ucomisd %xmm2, %xmm0
ja 0x2c719
movapd 0xd0(%rsp), %xmm0
ucomisd 0xdcbf3(%rip), %xmm0    # 0x109058
jbe 0x2c4bc
leaq 0x8(%r14), %rsi
movq 0x28(%rsp), %rdi
callq 0x69807
xorpd %xmm3, %xmm3
movsd 0xb0(%rsp), %xmm1
ucomisd %xmm1, %xmm0
ja 0x2c719
divsd %xmm1, %xmm0
movsd 0xdcbb8(%rip), %xmm1    # 0x109050
subsd %xmm0, %xmm1
movapd 0x10(%rsp), %xmm2
mulsd %xmm1, %xmm2
movsd 0x8(%rsp), %xmm0
movapd %xmm2, 0x10(%rsp)
ucomisd %xmm2, %xmm0
ja 0x2c719
movapd 0x70(%rsp), %xmm0
ucomisd 0xdcb8e(%rip), %xmm0    # 0x109058
jbe 0x2c5f3
leaq 0xf8(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x60(%rsp), %rdx
callq 0x9ccee
leaq 0x8(%r14), %r15
movq %r15, %rdi
leaq 0xf8(%rsp), %rsi
callq 0x699ea
movapd %xmm0, 0xc0(%rsp)
xorpd %xmm3, %xmm3
movapd 0xc0(%rsp), %xmm0
ucomisd 0x70(%rsp), %xmm0
ja 0x2c719
leaq 0x20(%r14), %rdx
leaq 0xf8(%rsp), %rdi
movq %r15, %rsi
callq 0x9ccee
movq 0x28(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x699ea
ucomisd 0x70(%rsp), %xmm0
jbe 0x2c5a5
xorpd %xmm3, %xmm3
jmp 0x2c719
movsd 0x98(%r13), %xmm0
minsd 0x98(%r14), %xmm0
xorpd %xmm3, %xmm3
movsd 0x68(%rsp), %xmm1
ucomisd %xmm1, %xmm0
ja 0x2c719
divsd %xmm1, %xmm0
movsd 0xdcaca(%rip), %xmm1    # 0x109050
subsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
movapd %xmm1, 0x10(%rsp)
ucomisd %xmm1, %xmm0
jbe 0x2c3ef
jmp 0x2c719
movapd 0xc0(%rsp), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
divpd 0xe0(%rsp), %xmm1
movapd 0xdcfbd(%rip), %xmm0    # 0x109580
subpd %xmm1, %xmm0
movapd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
mulsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
movapd %xmm1, 0x10(%rsp)
ucomisd %xmm1, %xmm0
xorpd %xmm3, %xmm3
ja 0x2c719
movsd 0x58(%rsp), %xmm0
ucomisd 0xdca57(%rip), %xmm0    # 0x109058
jbe 0x2c68b
leaq 0x20(%r14), %rsi
movq 0x60(%rsp), %rdi
callq 0x9ee8e
movapd %xmm0, %xmm1
ucomisd 0xdda2f(%rip), %xmm0    # 0x10a050
movsd 0x90(%rsp), %xmm0
jbe 0x2c647
xorpd %xmm0, %xmm0
movsd 0xdca18(%rip), %xmm2    # 0x109050
ucomisd %xmm1, %xmm2
jbe 0x2c647
movapd %xmm1, %xmm0
callq 0x155b0
xorpd %xmm3, %xmm3
movsd 0x58(%rsp), %xmm1
ucomisd %xmm1, %xmm0
ja 0x2c719
divsd %xmm1, %xmm0
movsd 0xdc9e9(%rip), %xmm1    # 0x109050
subsd %xmm0, %xmm1
movapd 0x10(%rsp), %xmm2
mulsd %xmm1, %xmm2
movsd 0x8(%rsp), %xmm0
movapd %xmm2, 0x10(%rsp)
ucomisd %xmm2, %xmm0
ja 0x2c719
movsd 0x98(%rsp), %xmm2
ucomisd 0xdc9bc(%rip), %xmm2    # 0x109058
jbe 0x2c713
movupd 0x78(%r13), %xmm0
movupd 0x78(%r14), %xmm1
subpd %xmm1, %xmm0
movapd 0xdceba(%rip), %xmm3    # 0x109570
andpd %xmm3, %xmm0
pshufd $0xee, %xmm0, %xmm1     # xmm1 = xmm0[2,3,2,3]
addsd %xmm0, %xmm1
movsd 0x88(%r13), %xmm0
subsd 0x88(%r14), %xmm0
andpd %xmm3, %xmm0
addsd %xmm1, %xmm0
xorpd %xmm3, %xmm3
ucomisd %xmm2, %xmm0
ja 0x2c719
divsd %xmm2, %xmm0
movsd 0xdc95d(%rip), %xmm1    # 0x109050
subsd %xmm0, %xmm1
movapd 0x10(%rsp), %xmm2
mulsd %xmm1, %xmm2
movsd 0x8(%rsp), %xmm0
ucomisd %xmm2, %xmm0
ja 0x2c719
movapd %xmm2, %xmm3
jmp 0x2c719
movapd 0x10(%rsp), %xmm3
movsd 0x8(%rsp), %xmm0
ucomisd %xmm3, %xmm0
jae 0x2c778
movl 0xbc(%r13), %edx
testl %ebx, %ebx
jle 0x2c76d
movl %ebx, %ecx
movl 0x44(%rsp), %eax
subl %ebp, %eax
subl %edx, %ecx
cmpl %ecx, %eax
jle 0x2c76d
movl %edx, %ecx
sarl $0x1f, %ecx
andl %edx, %ecx
leal 0x1(%rdx), %eax
movq %rdx, %rsi
testl %esi, %esi
jle 0x2c78b
movq (%r12), %rdi
movq -0x8(%rdi,%rsi,8), %rdi
decq %rsi
movsd 0xc8(%rdi), %xmm0
decl %eax
ucomisd %xmm3, %xmm0
jbe 0x2c74b
jmp 0x2c78d
movq %r12, %rdi
movq %r14, %rsi
callq 0xc35c2
incq %rbp
movslq 0x44(%rsp), %rax
cmpq %rax, %rbp
jl 0x2c382
jmp 0x2c7dd
movl %ecx, %eax
cmpl %ebx, %eax
jge 0x2c7b8
movsd %xmm3, 0xc8(%r14)
movq %r12, %rdi
movq %r14, %rsi
movl %eax, %edx
callq 0xc35c2
movq %r12, %rdi
movl %ebx, %esi
callq 0xc37c4
movl 0xbc(%r13), %edx
cmpl %ebx, %edx
jne 0x2c778
movq (%r12), %rax
movq 0x88(%rsp), %rcx
movq -0x8(%rax,%rcx,8), %rax
movsd 0xc8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
jmp 0x2c778
leaq 0x38(%rsp), %r14
movq %r14, %rdi
callq 0xc3596
movq 0xa8(%rsp), %rcx
incq %rcx
movq 0xa0(%rsp), %r15
movslq 0xc(%r15), %rax
cmpq %rax, %rcx
movl %ebx, %ebp
jl 0x2c26d
testl %eax, %eax
jle 0x2c82c
movq (%r15), %rcx
xorl %edx, %edx
movq (%rcx,%rdx,8), %rsi
movq $0x0, 0xc8(%rsi)
incq %rdx
cmpq %rdx, %rax
jne 0x2c815
leaq 0x1c8(%rsp), %rdi
callq 0xc3596
movl $0x1, %eax
addq $0x1f8, %rsp            # imm = 0x1F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x60, %esi
movq %r14, %rdi
callq 0x15620
jmp 0x2c87a
jmp 0x2c864
movq %rax, %rbx
jmp 0x2c87a
jmp 0x2c86d
jmp 0x2c86d
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0xc3596
leaq 0x1c8(%rsp), %rdi
callq 0xc3596
movq %rbx, %rdi
callq 0x15ad0
nop