// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelTree.cpp
// Function: gaps::R3SurfelTree::SplitLeafNodes(gaps::R3SurfelNode*, gaps::R3SurfelConstraint const&, gaps::RNArray<gaps::R3SurfelNode*>*, gaps::RNArray<gaps::R3SurfelNode*>*)
int R3SurfelTree::
SplitLeafNodes(R3SurfelNode *node, const R3SurfelConstraint& constraint, 
  RNArray<R3SurfelNode *> *nodesA, RNArray<R3SurfelNode *> *nodesB)
{
  // Initialize return value (whether any node was split)
  int status = 0;

  // Check if node is a leaf
  if (node->NParts() == 0) {
    // Check constraint
    int check = constraint.Check(node->BBox());
    if (check == R3_SURFEL_CONSTRAINT_PASS) {
      if (nodesA) nodesA->Insert(node);
    }
    else if (check == R3_SURFEL_CONSTRAINT_FAIL) {
      if (nodesB) nodesB->Insert(node);
    }
    else {
      // Split blocks in leaf node
      RNArray<R3SurfelBlock *> blocksA, blocksB;
      if (SplitBlocks(node, constraint, &blocksA, &blocksB)) {
        // Create new nodes
        R3SurfelNode *nodeA = new R3SurfelNode();
        R3SurfelNode *nodeB = new R3SurfelNode();

        // Move blocks from node to nodeA
        for (int i = 0; i < blocksA.NEntries(); i++) {
          R3SurfelBlock *block = blocksA.Kth(i);
          node->RemoveBlock(block);
          nodeA->InsertBlock(block);
        }
    
        // Move blocks from node to nodeB
        for (int i = 0; i < blocksB.NEntries(); i++) {
          R3SurfelBlock *block = blocksB.Kth(i);
          node->RemoveBlock(block);
          nodeB->InsertBlock(block);
        }
    
        // Insert new nodes into tree
        InsertNode(nodeA, node);
        InsertNode(nodeB, node);

        // Update return values
        if (nodesA) nodesA->Insert(nodeA);
        if (nodesB) nodesB->Insert(nodeB);
        status = 1;
      }
      else {
        // Blocks were all inside or outside constraint, update return values
        if (nodesA && !blocksA.IsEmpty()) nodesA->Insert(node);
        if (nodesB && !blocksB.IsEmpty()) nodesB->Insert(node);
      }
    }
  }
  else {
    // Check constraint
    if (!nodesA || !nodesB) {
      int check = constraint.Check(node->BBox());
      if ((check == R3_SURFEL_CONSTRAINT_PASS) && !nodesA) return 0;
      if ((check == R3_SURFEL_CONSTRAINT_FAIL) && !nodesB) return 0;
    }

    // Consider each child node
    for (int i = 0; i < node->NParts(); i++) {
      R3SurfelNode *part = node->Part(i);
      status |= SplitLeafNodes(part, constraint, nodesA, nodesB);
    }
  }

  // Return whether any nodes were split
  return status;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r8, %rbx
movq %rcx, %r15
movq %rdx, %rbp
movq %rsi, %r14
movq %rdi, 0x10(%rsp)
cmpl $0x0, 0x3c(%rsi)
je 0x36326
movq %r15, %r12
testq %r15, %r15
setne %al
testq %rbx, %rbx
setne %cl
testb %cl, %al
jne 0x362ed
movq %rbx, %r15
testq %rbx, %rbx
setne %bl
testq %r12, %r12
sete 0x8(%rsp)
movq %r14, %rdi
callq 0x33720
movq (%rbp), %rcx
movq %rbp, %rdi
movq %rax, %rsi
callq *0x30(%rcx)
cmpl $0x2, %eax
sete %cl
testl %eax, %eax
setne %al
xorl %r13d, %r13d
testb %cl, 0x8(%rsp)
jne 0x364d5
orb %al, %bl
movq %r15, %rbx
je 0x364d5
movq %rbx, %r15
xorl %ebx, %ebx
xorl %r13d, %r13d
movslq 0x3c(%r14), %rax
cmpq %rax, %rbx
jge 0x364d5
movq 0x30(%r14), %rax
movq (%rax,%rbx,8), %rsi
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rdx
movq %r12, %rcx
movq %r15, %r8
callq *0x30(%rax)
orl %eax, %r13d
incq %rbx
jmp 0x362f5
movq %r14, %rdi
callq 0x33720
movq (%rbp), %rcx
movq %rbp, %rdi
movq %rax, %rsi
callq *0x30(%rcx)
testl %eax, %eax
je 0x36355
cmpl $0x2, %eax
jne 0x36371
xorl %r13d, %r13d
testq %r15, %r15
je 0x364d5
movq %r15, %rdi
jmp 0x36364
xorl %r13d, %r13d
testq %rbx, %rbx
je 0x364d5
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1784c
jmp 0x364d5
movq %r15, 0x8(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x9a7ae
leaq 0x18(%rsp), %rdi
callq 0x9a7ae
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
leaq 0x28(%rsp), %rcx
leaq 0x18(%rsp), %r8
movq %r14, %rsi
movq %rbp, %rdx
callq *0x58(%rax)
testl %eax, %eax
je 0x3648b
movl $0xd0, %edi
callq 0x134f0
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
callq 0x33394
movl $0xd0, %edi
callq 0x134f0
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
callq 0x33394
xorl %ebp, %ebp
movslq 0x34(%rsp), %rax
cmpq %rax, %rbp
jge 0x3640e
movq 0x28(%rsp), %rax
movq (%rax,%rbp,8), %r13
movq (%r14), %rax
movq %r14, %rdi
movq %r13, %rsi
callq *0x30(%rax)
movq (%r12), %rax
movq %r12, %rdi
movq %r13, %rsi
callq *0x28(%rax)
incq %rbp
jmp 0x363dd
xorl %ebp, %ebp
movslq 0x24(%rsp), %rax
cmpq %rax, %rbp
jge 0x36440
movq 0x18(%rsp), %rax
movq (%rax,%rbp,8), %r13
movq (%r14), %rax
movq %r14, %rdi
movq %r13, %rsi
callq *0x30(%rax)
movq %r15, %rdi
movq (%r15), %rax
movq %r13, %rsi
callq *0x28(%rax)
incq %rbp
jmp 0x36410
movq 0x10(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x34e72
movq 0x10(%rsp), %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x34e72
cmpq $0x0, 0x8(%rsp)
je 0x36475
movq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x1784c
pushq $0x1
popq %r13
testq %rbx, %rbx
je 0x364c1
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1784c
jmp 0x364c1
cmpq $0x0, 0x8(%rsp)
je 0x364a7
cmpl $0x0, 0x34(%rsp)
je 0x364a7
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x1784c
xorl %r13d, %r13d
testq %rbx, %rbx
je 0x364c1
cmpl $0x0, 0x24(%rsp)
je 0x364c1
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1784c
leaq 0x18(%rsp), %rdi
callq 0x9a81c
leaq 0x28(%rsp), %rdi
callq 0x9a81c
movl %r13d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0xd0, %esi
movq %r15, %rdi
jmp 0x364ff
movq %rax, %rbx
movl $0xd0, %esi
movq %r12, %rdi
callq 0x13500
jmp 0x36516
jmp 0x36513
movq %rax, %rbx
jmp 0x36520
jmp 0x36513
jmp 0x36513
jmp 0x36513
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x9a81c
leaq 0x28(%rsp), %rdi
callq 0x9a81c
movq %rbx, %rdi
callq 0x138f0