// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/apps/msh2df/../../pkgs/R3Shapes/R3Kdtree.cpp
// Function: gaps::R3Kdtree<Point*>::InsertPoints(gaps::R3KdtreeNode<Point*>*, gaps::R3Box const&, Point**, int)
void R3Kdtree<PtrType>::
InsertPoints(R3KdtreeNode<PtrType> *node, const R3Box& node_box, PtrType *points, int npoints) 
{
  // Make sure node is an empty leaf
  assert(node);
  assert(node->children[0] == NULL);
  assert(node->children[1] == NULL);
  assert(node->npoints == 0);

  // Check number of points
  if (npoints < R3kdtree_max_points_per_node) {
    // Insert new points into leaf node and return
    for (int i = 0; i < npoints; i++) {
      node->points[node->npoints++] = points[i];
    }
  }
  else {
    // Find dimension to split along
    node->split_dimension = node_box.LongestAxis();
    
    // Partition points according to coordinates in split_dimension
    int split_index = PartitionPoints(points, npoints, node->split_dimension, 0, npoints-1);
    assert((split_index >= 0) && (split_index < npoints));

    // Determine split coordinate
    node->split_coordinate = Position(points[split_index])[node->split_dimension];
    assert(node->split_coordinate >= node_box[RN_LO][node->split_dimension]);
    assert(node->split_coordinate <= node_box[RN_HI][node->split_dimension]);

    // Construct children node boxes
    R3Box node0_box(node_box);
    R3Box node1_box(node_box);
    node0_box[RN_HI][node->split_dimension] = node->split_coordinate;
    node1_box[RN_LO][node->split_dimension] = node->split_coordinate;

    // Create children
    node->children[0] = new R3KdtreeNode<PtrType>(node);
    node->children[1] = new R3KdtreeNode<PtrType>(node);

    // Insert points into children
    InsertPoints(node->children[0], node0_box, points, split_index);
    InsertPoints(node->children[1], node1_box, &points[split_index], npoints - split_index);

    // Increment number of nodes
    nnodes += 2;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %r8d, %r15d
movq %rcx, %r14
movq %rsi, %rbx
cmpl $0x1f, %r8d
jg 0x1501b
testl %r15d, %r15d
jle 0x15138
movslq 0x128(%rbx), %rcx
movl %ecx, %eax
movl %r15d, %edx
leaq (%rbx,%rcx,8), %rsi
addq $0x28, %rsi
xorl %ecx, %ecx
movq (%r14,%rcx,8), %rdi
movq %rdi, (%rsi,%rcx,8)
incq %rcx
cmpq %rcx, %rdx
jne 0x14ffe
addl %ecx, %eax
movl %eax, 0x128(%rbx)
jmp 0x15138
movq %rdx, %r13
movq %rdi, %r12
movq %rdx, %rdi
callq 0x3b04a
movl %eax, 0x20(%rbx)
leal -0x1(%r15), %r9d
movq %r12, %rdi
movq %r14, %rsi
movl %r15d, %edx
movl %eax, %ecx
xorl %r8d, %r8d
callq 0x1516c
movl %eax, %ebp
cltq
movq %rax, (%rsp)
movq (%r14,%rax,8), %rdx
leaq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x14f6e
movslq 0x20(%rbx), %rax
movsd 0x8(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x18(%rbx)
leaq 0x8(%rsp), %rdi
movq %r13, %rsi
callq 0x3aa88
leaq 0x40(%rsp), %rdi
movq %r13, %rsi
callq 0x3aa88
movsd 0x18(%rbx), %xmm0
movslq 0x20(%rbx), %rax
movsd %xmm0, 0x28(%rsp,%rax,8)
movsd %xmm0, 0x48(%rsp,%rax,8)
movl $0x130, %edi            # imm = 0x130
callq 0xe440
movq %rax, %r13
movq %rbx, (%rax)
movl $0x0, 0x128(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
movq %rax, 0x8(%rbx)
movl $0x130, %edi            # imm = 0x130
callq 0xe440
movq %rbx, (%rax)
movl $0x0, 0x128(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
movq %rax, 0x10(%rbx)
leaq 0x8(%rsp), %rdx
movq %r12, %rdi
movq %r13, %rsi
movq %r14, %rcx
movl %ebp, %r8d
callq 0x14fc2
movq (%rsp), %rax
leaq (%r14,%rax,8), %rcx
movq 0x10(%rbx), %rsi
subl %ebp, %r15d
leaq 0x40(%rsp), %rdx
movq %r12, %rdi
movl %r15d, %r8d
callq 0x14fc2
addl $0x2, 0x5c(%r12)
leaq 0x40(%rsp), %rdi
callq 0x3b8a8
leaq 0x8(%rsp), %rdi
callq 0x3b8a8
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x15159
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x3b8a8
leaq 0x8(%rsp), %rdi
callq 0x3b8a8
movq %rbx, %rdi
callq 0xe7f0
nop