// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelUtils.cpp
// Function: gaps::InsertNodes(gaps::R3SurfelNodeSet*, gaps::R3SurfelTree*, gaps::R3SurfelNode*, gaps::R3SurfelConstraint const*, gaps::R3Point const&, double, double, double, double)
static int
InsertNodes(R3SurfelNodeSet *nodeset, 
  R3SurfelTree *tree, R3SurfelNode *node,
  const R3SurfelConstraint *constraint,
  const R3Point& xycenter, RNLength xyradius,
  RNScalar center_resolution, RNScalar perimeter_resolution,
  RNScalar focus_exponent)
{
  // Check if node satisfies constraint
  if (constraint && !constraint->Check(node)) {
    return 0;
  }

  // Check if node is outside perimeter
  if ((perimeter_resolution == 0) && (xyradius > 0)) {
    RNScalar xydistance = XYDistance(xycenter, node->BBox());
    if (xydistance > xyradius) return 0;
  }

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

  // Check if this node has target resolution 
  if ((node->NBlocks() > 0) && (center_resolution > 0)) {
    // Compute the target resolution at node
    RNScalar target_resolution = center_resolution;
    if ((xyradius > 0) && (perimeter_resolution < center_resolution)) {
      RNLength xydistance =  XYDistance(xycenter, node->BBox());
      RNScalar t = 1 - xydistance / xyradius;
      target_resolution = perimeter_resolution + 
        (center_resolution - perimeter_resolution) * pow(t, focus_exponent);
    }
      
    // Check if this node is within the target resolution
    for (int i = 0; i < node->NParts(); i++) {
      R3SurfelNode *part = node->Part(i);
      if (part->Resolution() > target_resolution) {
        nodeset->InsertNode(node);
        return 1;
      }
    }
  }

  // Consider parts
  int status = 0;
  for (int i = 0; i < node->NParts(); i++) {
    R3SurfelNode *part = node->Part(i);
    status |= InsertNodes(nodeset, tree, part, constraint, xycenter, xyradius, 
      center_resolution, perimeter_resolution, focus_exponent);
  }

  // Return whether anything was added
  return status;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movsd %xmm3, 0x20(%rsp)
movsd %xmm2, 0x8(%rsp)
movsd %xmm1, 0x18(%rsp)
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %rbx
movq %rdi, %r14
testq %rdx, %rdx
movsd %xmm0, 0x10(%rsp)
je 0x273e4
movq (%r12), %rax
movq %r12, %rdi
movq %rbx, %rsi
callq *0x18(%rax)
movsd 0x10(%rsp), %xmm0
testl %eax, %eax
je 0x2752a
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jbe 0x2741b
movsd 0x8(%rsp), %xmm1
ucomisd %xmm2, %xmm1
jne 0x2741b
jp 0x2741b
movq %rbx, %rdi
callq 0x3755c
movq %r15, %rdi
movq %rax, %rsi
callq 0x2a854
ucomisd 0x10(%rsp), %xmm0
ja 0x2752a
movl 0x3c(%rbx), %eax
testl %eax, %eax
je 0x2752e
xorpd %xmm0, %xmm0
movsd 0x18(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x274e3
cmpl $0x0, 0x4c(%rbx)
jle 0x274e3
movsd 0x10(%rsp), %xmm2
ucomisd %xmm0, %xmm2
jbe 0x274b7
ucomisd 0x8(%rsp), %xmm1
movsd %xmm1, (%rsp)
jbe 0x274bc
movq %rbx, %rdi
callq 0x3755c
movq %r15, %rdi
movq %rax, %rsi
callq 0x2a854
divsd 0x10(%rsp), %xmm0
movsd 0xb5cca(%rip), %xmm1    # 0xdd148
subsd %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
subsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rsp)
movapd %xmm1, %xmm0
movsd 0x20(%rsp), %xmm1
callq 0x138a0
mulsd (%rsp), %xmm0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rsp)
movl 0x3c(%rbx), %eax
jmp 0x274bc
movsd %xmm1, (%rsp)
testl %eax, %eax
jle 0x2752a
xorl %r13d, %r13d
movq 0x30(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x37452
ucomisd (%rsp), %xmm0
ja 0x2752e
incq %r13
movslq 0x3c(%rbx), %rax
cmpq %rax, %r13
jl 0x274c3
testl %eax, %eax
jle 0x2752a
xorl %r13d, %r13d
xorl %ebp, %ebp
movq 0x30(%rbx), %rax
movq (%rax,%r13,8), %rsi
movq %r14, %rdi
movq %r12, %rdx
movq %r15, %rcx
movsd 0x10(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
movsd 0x8(%rsp), %xmm2
movsd 0x20(%rsp), %xmm3
callq 0x27392
orl %eax, %ebp
incq %r13
movslq 0x3c(%rbx), %rax
cmpq %rax, %r13
jl 0x274ec
jmp 0x2753f
xorl %ebp, %ebp
jmp 0x2753f
movq (%r14), %rax
movq %r14, %rdi
movq %rbx, %rsi
callq *0x38(%rax)
movl $0x1, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq