// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelNodeSet.cpp
// Function: gaps::R3SurfelNodeSet::InsertNodes(gaps::R3SurfelTree*, gaps::R3SurfelNode*, gaps::R3Point const&, double, double, double, double, double, double)
void R3SurfelNodeSet::
InsertNodes(R3SurfelTree *tree, R3SurfelNode *node,
  const R3Point& xycenter, RNLength xyradius, 
  RNCoord zmin, RNCoord zmax,
  RNScalar center_resolution, RNScalar perimeter_resolution,
  RNScalar focus_exponent)
{
  // Check if node is in infinite cylinder
  if (node->BBox().ZMin() > zmax) return;
  if (node->BBox().ZMax() < zmin) return;
  RNLength squared_xydistance = SquaredXYDistance(xycenter, node->BBox());
  if ((xyradius > 0) && (squared_xydistance > xyradius * xyradius)) return;

  // Check if this node is a leaf
  if (node->NParts() == 0) {
    // Simply insert leaf node
    InsertNode(node);
    return;
  }

  // Check if we are selecting interior nodes based on resolution
  if (center_resolution > 0) {
    // Compute the target resolution at this node position
    RNScalar target_resolution = center_resolution;
    if ((xyradius > 0) && (perimeter_resolution > 0)) {
      RNLength xydistance = sqrt(squared_xydistance);
      RNScalar t = 1 - xydistance / xyradius;
      target_resolution = perimeter_resolution + 
        (center_resolution - perimeter_resolution) * pow(t, focus_exponent);
    }

    // Check if this node is within a factor of two of target resolution
    if (node->Resolution() > 0.5 * target_resolution) {
      // Insert all parts of this node and don't recurse 
      for (int i = 0; i < node->NParts(); i++) InsertNode(node->Part(i));
      return;
    }
  }

  // Recurse to parts 
  for (int i = 0; i < node->NParts(); i++) {
    R3SurfelNode *part = node->Part(i);
    InsertNodes(tree, part, xycenter, xyradius, zmin, zmax, center_resolution, perimeter_resolution);
  }
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0xa0(%rsp)
movq %rsi, 0x98(%rsp)
movq %rdx, 0x90(%rsp)
movq %rcx, 0x88(%rsp)
movsd %xmm0, 0x80(%rsp)
movsd %xmm1, 0x78(%rsp)
movsd %xmm2, 0x70(%rsp)
movsd %xmm3, 0x68(%rsp)
movsd %xmm4, 0x60(%rsp)
movsd %xmm5, 0x58(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x90(%rsp), %rdi
callq 0x5ee30
movq %rax, %rdi
callq 0x435e0
ucomisd 0x70(%rsp), %xmm0
jbe 0x6142d
jmp 0x616b3
movq 0x90(%rsp), %rdi
callq 0x5ee30
movq %rax, %rdi
callq 0x44e40
movaps %xmm0, %xmm1
movsd 0x78(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x61456
jmp 0x616b3
movq 0x88(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x90(%rsp), %rdi
callq 0x5ee30
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x616c0
movsd %xmm0, 0x50(%rsp)
movsd 0x80(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x614b8
movsd 0x50(%rsp), %xmm0
movsd 0x80(%rsp), %xmm1
mulsd 0x80(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x614b8
jmp 0x616b3
movq 0x90(%rsp), %rdi
callq 0x31660
cmpl $0x0, %eax
jne 0x614e2
movq 0x20(%rsp), %rdi
movq 0x90(%rsp), %rsi
movq (%rdi), %rax
callq *0x38(%rax)
jmp 0x616b3
movsd 0x68(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x6161f
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x80(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x615a4
movsd 0x60(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x615a4
movsd 0x50(%rsp), %xmm0
callq 0x13420
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm1
divsd 0x80(%rsp), %xmm1
movsd 0x142c1a(%rip), %xmm0   # 0x1a4168
subsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x68(%rsp), %xmm0
subsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x38(%rsp), %xmm0
movsd 0x58(%rsp), %xmm1
callq 0x13960
movsd 0x8(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x10(%rsp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
movq 0x90(%rsp), %rdi
callq 0x5ecf0
movsd 0x142b9f(%rip), %xmm1   # 0x1a4158
mulsd 0x48(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x6161d
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
movl %eax, 0x4(%rsp)
movq 0x90(%rsp), %rdi
callq 0x31660
movl %eax, %ecx
movl 0x4(%rsp), %eax
cmpl %ecx, %eax
jge 0x61618
movq 0x90(%rsp), %rdi
movl 0x34(%rsp), %esi
callq 0x43680
movq 0x20(%rsp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
callq *0x38(%rax)
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x615cd
jmp 0x616b3
jmp 0x6161f
movl $0x0, 0x30(%rsp)
movl 0x30(%rsp), %eax
movl %eax, (%rsp)
movq 0x90(%rsp), %rdi
callq 0x31660
movl %eax, %ecx
movl (%rsp), %eax
cmpl %ecx, %eax
jge 0x616b3
movq 0x90(%rsp), %rdi
movl 0x30(%rsp), %esi
callq 0x43680
movq 0x20(%rsp), %rdi
movq %rax, 0x28(%rsp)
movq 0x98(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq 0x88(%rsp), %rcx
movsd 0x80(%rsp), %xmm0
movsd 0x78(%rsp), %xmm1
movsd 0x70(%rsp), %xmm2
movsd 0x68(%rsp), %xmm3
movsd 0x60(%rsp), %xmm4
movq (%rdi), %rax
movsd 0x143458(%rip), %xmm5   # 0x1a4af8
callq *0x30(%rax)
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x61627
addq $0xa8, %rsp
retq
nopl (%rax,%rax)