// File: /workspace/github_cpp_makefile_star2_O3/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, %r13
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbp
movl 0x3c(%rsi), %eax
testl %eax, %eax
je 0x3a637
testq %r13, %r13
setne %cl
testq %rbx, %rbx
setne %dl
testb %dl, %cl
movq %r15, 0x8(%rsp)
jne 0x3a5f4
movq %r14, %rdi
movq %r15, %r14
movq %rbx, %r15
testq %rbx, %rbx
setne %bl
movq %r13, %r12
testq %r13, %r13
sete (%rsp)
movq %rdi, 0x30(%rsp)
callq 0x3755c
movq (%r14), %rcx
movq %r14, %rdi
movq %rax, %rsi
callq *0x30(%rcx)
cmpl $0x2, %eax
sete %cl
testl %eax, %eax
setne %al
xorl %r13d, %r13d
testb %cl, (%rsp)
jne 0x3a80e
orb %al, %bl
movq 0x30(%rsp), %r14
je 0x3a80e
movl 0x3c(%r14), %eax
movq %r15, %rbx
movq %r12, %r13
testl %eax, %eax
jle 0x3a668
movq %rbx, %r15
xorl %ebx, %ebx
movq %rbp, %r12
movq %r13, %rbp
xorl %r13d, %r13d
movq 0x30(%r14), %rax
movq (%rax,%rbx,8), %rsi
movq (%r12), %rax
movq %r12, %rdi
movq 0x8(%rsp), %rdx
movq %rbp, %rcx
movq %r15, %r8
callq *0x30(%rax)
orl %eax, %r13d
incq %rbx
movslq 0x3c(%r14), %rax
cmpq %rax, %rbx
jl 0x3a606
jmp 0x3a80e
movq %r14, %rdi
callq 0x3755c
movq (%r15), %rcx
movq %r15, %rdi
movq %rax, %rsi
callq *0x30(%rcx)
testl %eax, %eax
je 0x3a670
cmpl $0x2, %eax
jne 0x3a68f
movq %r13, %rdi
xorl %r13d, %r13d
testq %rdi, %rdi
je 0x3a80e
movl 0xc(%rdi), %edx
jmp 0x3a682
xorl %r13d, %r13d
jmp 0x3a80e
xorl %r13d, %r13d
testq %rbx, %rbx
je 0x3a80e
movl 0xc(%rbx), %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0xa9d3e
jmp 0x3a80e
leaq 0x20(%rsp), %rdi
callq 0xa9ca8
leaq 0x10(%rsp), %rdi
callq 0xa9ca8
movq (%rbp), %rax
leaq 0x20(%rsp), %rcx
leaq 0x10(%rsp), %r8
movq %rbp, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq *0x58(%rax)
testl %eax, %eax
je 0x3a7c2
movl $0xd0, %edi
callq 0x134e0
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
callq 0x3715c
movl $0xd0, %edi
callq 0x134e0
movq %rax, %r12
movq %rbp, 0x8(%rsp)
movq %rax, %rdi
xorl %esi, %esi
callq 0x3715c
movq %r13, (%rsp)
cmpl $0x0, 0x2c(%rsp)
jle 0x3a733
xorl %ebp, %ebp
movq 0x20(%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
movslq 0x2c(%rsp), %rax
cmpq %rax, %rbp
jl 0x3a705
cmpl $0x0, 0x1c(%rsp)
jle 0x3a76b
xorl %ebp, %ebp
movq 0x10(%rsp), %rax
movq (%rax,%rbp,8), %r13
movq (%r14), %rax
movq %r14, %rdi
movq %r13, %rsi
callq *0x30(%rax)
movq %r12, %rdi
movq (%r12), %rax
movq %r13, %rsi
callq *0x28(%rax)
incq %rbp
movslq 0x1c(%rsp), %rax
cmpq %rax, %rbp
jl 0x3a73c
movq 0x8(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %r13
movq %r15, %rsi
movq %r14, %rdx
callq 0x38f02
movq (%rsp), %r15
movq %rbp, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x38f02
testq %r15, %r15
je 0x3a7a7
movl 0xc(%r15), %edx
movq %r15, %rdi
movq %r13, %rsi
callq 0xa9d3e
movl $0x1, %r13d
testq %rbx, %rbx
je 0x3a7fa
movl 0xc(%rbx), %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0xa9d3e
jmp 0x3a7fa
testq %r13, %r13
je 0x3a7dd
cmpl $0x0, 0x2c(%rsp)
je 0x3a7dd
movl 0xc(%r13), %edx
movq %r13, %rdi
movq %r14, %rsi
callq 0xa9d3e
xorl %r13d, %r13d
testq %rbx, %rbx
je 0x3a7fa
cmpl $0x0, 0x1c(%rsp)
je 0x3a7fa
movl 0xc(%rbx), %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0xa9d3e
leaq 0x10(%rsp), %rdi
callq 0xa9d12
leaq 0x20(%rsp), %rdi
callq 0xa9d12
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 %r12, %rdi
jmp 0x3a838
movq %rax, %rbx
movl $0xd0, %esi
movq %r15, %rdi
callq 0x134f0
jmp 0x3a84f
jmp 0x3a84c
movq %rax, %rbx
jmp 0x3a859
jmp 0x3a84c
jmp 0x3a84c
jmp 0x3a84c
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xa9d12
leaq 0x20(%rsp), %rdi
callq 0xa9d12
movq %rbx, %rdi
callq 0x138b0
nop