// File: /workspace/github_cpp_makefile_star2_O1/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 $0x1e8, %rsp            # imm = 0x1E8
movl %edx, %ebp
movsd %xmm6, 0x40(%rsp)
movsd %xmm5, 0x78(%rsp)
movsd %xmm4, 0x58(%rsp)
movsd %xmm3, 0xa0(%rsp)
movsd %xmm2, 0x30(%rsp)
movapd %xmm1, 0x80(%rsp)
movsd %xmm0, 0x60(%rsp)
movl %esi, %r14d
movq %rdi, %rbx
leaq 0x108(%rsp), %rdi
callq 0x29120
movl $0x60, %edi
callq 0x15610
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
movl $0x8, %edx
callq 0x1ab04
movq %r15, 0x10(%rbx)
movl 0xc(%rbx), %eax
testl %eax, %eax
jle 0x2cc93
movl %r14d, 0x2c(%rsp)
leaq 0xe9554(%rip), %rax     # 0x115ba8
movsd (%rax), %xmm0
movsd %xmm0, 0x98(%rsp)
movapd 0x80(%rsp), %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
movapd %xmm0, 0xd0(%rsp)
xorl %ecx, %ecx
leaq 0x48(%rsp), %r14
movq %rbx, 0x90(%rsp)
movsd 0x58(%rsp), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movq (%rbx), %rax
movq (%rax,%rcx,8), %r13
movsd 0x60(%rsp), %xmm2
jbe 0x2c6bf
movsd 0x50(%r13), %xmm0
ucomisd %xmm1, %xmm0
movsd 0x60(%rsp), %xmm2
jbe 0x2c6bf
mulsd 0x58(%rsp), %xmm0
movapd %xmm0, %xmm2
movapd %xmm2, 0x10(%rsp)
ucomisd %xmm1, %xmm2
jne 0x2c6e1
jp 0x2c6e1
movsd 0x50(%r13), %xmm0
mulsd 0xdfbbd(%rip), %xmm0    # 0x10c298
movapd %xmm0, 0x10(%rsp)
movq %rcx, 0xa8(%rsp)
movq %r14, %rdi
callq 0xc4b50
movapd 0x10(%rsp), %xmm3
movapd %xmm3, %xmm2
cmpeqsd 0xde954(%rip), %xmm2    # 0x10b058
movapd %xmm2, %xmm0
movsd 0xde940(%rip), %xmm1    # 0x10b050
andpd %xmm1, %xmm0
andnpd %xmm3, %xmm2
orpd %xmm0, %xmm2
movq 0x10(%rbx), %rdi
movq $0x0, (%rsp)
xorpd %xmm0, %xmm0
movq %r13, %rsi
movapd %xmm2, 0xc0(%rsp)
movapd %xmm2, %xmm1
movl 0x2c(%rsp), %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
movq %r14, %r9
callq 0x2f49c
testl %eax, %eax
je 0x2cc66
cmpl $0x0, 0x54(%rsp)
jle 0x2cc66
leaq 0x8(%r13), %rax
movq %rax, 0x38(%rsp)
movapd 0xc0(%rsp), %xmm0
mulsd %xmm0, %xmm0
movsd %xmm0, 0x70(%rsp)
leaq 0x20(%r13), %rax
movq %rax, 0x68(%rsp)
leaq 0xb0(%r13), %rbx
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
xorl %r14d, %r14d
movq 0x48(%rsp), %rax
movq (%rax,%r14,8), %r12
cmpq %r13, %r12
je 0x2cc55
testl %ebp, %ebp
je 0x2c7c4
movl 0xa8(%r13), %eax
cmpl 0xa8(%r12), %eax
jne 0x2cc55
movsd 0x40(%rsp), %xmm0
ucomisd 0xde886(%rip), %xmm0    # 0x10b058
movsd 0xde876(%rip), %xmm0    # 0x10b050
movapd %xmm0, 0x10(%rsp)
jbe 0x2c875
movl 0x90(%r13), %eax
movsd 0xde85b(%rip), %xmm0    # 0x10b050
movapd %xmm0, 0x10(%rsp)
cmpl 0x90(%r12), %eax
je 0x2c875
movsd 0x98(%r13), %xmm0
minsd 0x98(%r12), %xmm0
movsd 0x40(%rsp), %xmm2
ucomisd %xmm2, %xmm0
xorpd %xmm1, %xmm1
ja 0x2cba1
movapd %xmm0, %xmm3
divsd %xmm2, %xmm3
movsd 0xde814(%rip), %xmm2    # 0x10b050
subsd %xmm3, %xmm2
movsd 0x20(%rsp), %xmm3
ucomisd %xmm2, %xmm3
ja 0x2cba1
movsd 0x40(%rsp), %xmm1
cmpnltsd %xmm0, %xmm1
andpd %xmm1, %xmm2
movsd 0xde7e9(%rip), %xmm0    # 0x10b050
andnpd %xmm0, %xmm1
orpd %xmm2, %xmm1
movapd %xmm1, 0x10(%rsp)
movsd 0x78(%rsp), %xmm2
ucomisd 0xde7d5(%rip), %xmm2    # 0x10b058
jbe 0x2c8f1
movsd 0x68(%r13), %xmm0
subsd 0x68(%r12), %xmm0
andpd 0xdecd6(%rip), %xmm0    # 0x10b570
ucomisd %xmm2, %xmm0
xorpd %xmm1, %xmm1
ja 0x2cba1
movapd %xmm0, %xmm3
divsd %xmm2, %xmm3
movsd 0xde798(%rip), %xmm2    # 0x10b050
subsd %xmm3, %xmm2
mulsd 0x10(%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
ucomisd %xmm2, %xmm3
ja 0x2cba1
movsd 0x78(%rsp), %xmm1
cmpnltsd %xmm0, %xmm1
andpd %xmm1, %xmm2
andnpd 0x10(%rsp), %xmm1
orpd %xmm2, %xmm1
movapd %xmm1, 0x10(%rsp)
movapd 0xc0(%rsp), %xmm0
ucomisd 0xde756(%rip), %xmm0    # 0x10b058
jbe 0x2c970
leaq 0x8(%r12), %rsi
movq 0x38(%rsp), %rdi
callq 0x6a5ef
movsd 0x70(%rsp), %xmm2
ucomisd %xmm2, %xmm0
xorpd %xmm1, %xmm1
ja 0x2cba1
movapd %xmm0, %xmm3
divsd %xmm2, %xmm3
movsd 0xde719(%rip), %xmm2    # 0x10b050
subsd %xmm3, %xmm2
mulsd 0x10(%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
ucomisd %xmm2, %xmm3
ja 0x2cba1
movsd 0x70(%rsp), %xmm1
cmpnltsd %xmm0, %xmm1
andpd %xmm1, %xmm2
andnpd 0x10(%rsp), %xmm1
orpd %xmm2, %xmm1
movapd %xmm1, 0x10(%rsp)
movapd 0x80(%rsp), %xmm0
ucomisd 0xde6d7(%rip), %xmm0    # 0x10b058
jbe 0x2ca59
leaq 0xe8(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x68(%rsp), %rdx
callq 0x9e04e
leaq 0x8(%r12), %r15
movq %r15, %rdi
leaq 0xe8(%rsp), %rsi
callq 0x6a7d2
movapd %xmm0, 0xb0(%rsp)
movapd 0xb0(%rsp), %xmm0
ucomisd 0x80(%rsp), %xmm0
ja 0x2ca02
leaq 0x20(%r12), %rdx
leaq 0xe8(%rsp), %rdi
movq %r15, %rsi
callq 0x9e04e
movq 0x38(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x6a7d2
ucomisd 0x80(%rsp), %xmm0
jbe 0x2ca06
xorl %eax, %eax
jmp 0x2ca4d
movapd 0xb0(%rsp), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
divpd 0xd0(%rsp), %xmm1
movapd 0xdeb5c(%rip), %xmm0    # 0x10b580
subpd %xmm1, %xmm0
movapd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
mulsd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
movapd %xmm1, 0x10(%rsp)
ucomisd %xmm1, %xmm0
setbe %al
xorpd %xmm1, %xmm1
testb %al, %al
je 0x2cba1
movsd 0x30(%rsp), %xmm0
ucomisd 0xde5f1(%rip), %xmm0    # 0x10b058
jbe 0x2cb11
leaq 0x20(%r12), %rsi
movq 0x68(%rsp), %rdi
callq 0xa01fe
movapd %xmm0, %xmm1
ucomisd 0xdf5c8(%rip), %xmm0    # 0x10c050
movsd 0x98(%rsp), %xmm0
movsd 0x30(%rsp), %xmm2
jbe 0x2caba
xorpd %xmm0, %xmm0
movsd 0xde5ab(%rip), %xmm3    # 0x10b050
ucomisd %xmm1, %xmm3
jbe 0x2caba
movapd %xmm1, %xmm0
callq 0x155b0
movsd 0x30(%rsp), %xmm2
ucomisd %xmm2, %xmm0
xorpd %xmm1, %xmm1
ja 0x2cba1
movapd %xmm0, %xmm3
divsd %xmm2, %xmm3
movsd 0xde578(%rip), %xmm2    # 0x10b050
subsd %xmm3, %xmm2
mulsd 0x10(%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
ucomisd %xmm2, %xmm3
ja 0x2cba1
movsd 0x30(%rsp), %xmm1
cmpnltsd %xmm0, %xmm1
andpd %xmm1, %xmm2
andnpd 0x10(%rsp), %xmm1
orpd %xmm2, %xmm1
movapd %xmm1, 0x10(%rsp)
movsd 0xa0(%rsp), %xmm2
ucomisd 0xde536(%rip), %xmm2    # 0x10b058
jbe 0x2cb9b
movupd 0x78(%r13), %xmm0
movupd 0x78(%r12), %xmm1
subpd %xmm1, %xmm0
movapd 0xdea33(%rip), %xmm3    # 0x10b570
andpd %xmm3, %xmm0
pshufd $0xee, %xmm0, %xmm1     # xmm1 = xmm0[2,3,2,3]
addsd %xmm0, %xmm1
movsd 0x88(%r13), %xmm0
subsd 0x88(%r12), %xmm0
andpd %xmm3, %xmm0
addsd %xmm1, %xmm0
ucomisd %xmm2, %xmm0
xorpd %xmm1, %xmm1
ja 0x2cba1
divsd %xmm2, %xmm0
movsd 0xde4d5(%rip), %xmm2    # 0x10b050
subsd %xmm0, %xmm2
movapd 0x10(%rsp), %xmm3
mulsd %xmm2, %xmm3
movsd 0x20(%rsp), %xmm0
ucomisd %xmm3, %xmm0
ja 0x2cba1
movapd %xmm3, %xmm1
jmp 0x2cba1
movapd 0x10(%rsp), %xmm1
movsd 0x20(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jae 0x2cc55
movl 0x2c(%rsp), %ecx
testl %ecx, %ecx
jle 0x2cc43
movl 0x54(%rsp), %eax
subl %r14d, %eax
movl 0xbc(%r13), %edx
subl %edx, %ecx
cmpl %ecx, %eax
jle 0x2cc43
testl %edx, %edx
jle 0x2cbf5
leal -0x1(%rdx), %eax
movq (%rbx), %rcx
movslq %edx, %rsi
movq -0x8(%rcx,%rsi,8), %rcx
movsd 0xc8(%rcx), %xmm0
ucomisd %xmm1, %xmm0
ja 0x2cbf3
movl %eax, %edx
jbe 0x2cbd1
movl 0x2c(%rsp), %r15d
cmpl %r15d, %edx
jge 0x2cc1f
movsd %xmm1, 0xc8(%r12)
movq %rbx, %rdi
movq %r12, %rsi
callq 0xc4be6
movq %rbx, %rdi
movl %r15d, %esi
callq 0xc4dc8
movslq 0xbc(%r13), %rax
cmpl %r15d, %eax
jne 0x2cc55
movq (%rbx), %rcx
movq -0x8(%rcx,%rax,8), %rax
movsd 0xc8(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
jmp 0x2cc55
movl 0xbc(%r13), %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0xc4be6
incq %r14
movslq 0x54(%rsp), %rax
cmpq %rax, %r14
jl 0x2c799
leaq 0x48(%rsp), %r14
movq %r14, %rdi
callq 0xc4bba
movq 0xa8(%rsp), %rcx
incq %rcx
movq 0x90(%rsp), %rbx
movslq 0xc(%rbx), %rax
cmpq %rax, %rcx
jl 0x2c686
testl %eax, %eax
jle 0x2ccb5
movq (%rbx), %rcx
movl %eax, %eax
xorl %edx, %edx
movq (%rcx,%rdx,8), %rsi
movq $0x0, 0xc8(%rsi)
incq %rdx
cmpq %rdx, %rax
jne 0x2cc9e
leaq 0x1b8(%rsp), %rdi
callq 0xc4bba
movl $0x1, %eax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x60, %esi
movq %r15, %rdi
callq 0x15620
jmp 0x2cd03
jmp 0x2cced
movq %rax, %rbx
jmp 0x2cd03
jmp 0x2ccf6
jmp 0x2ccf6
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0xc4bba
leaq 0x1b8(%rsp), %rdi
callq 0xc4bba
movq %rbx, %rdi
callq 0x15ae0