// File: /workspace/github_cpp_makefile_star2_O1/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, %r13
movq %rsi, %r14
movq %rdi, %r12
cmpl $0x0, 0x3c(%rsi)
je 0x3a9eb
testq %r15, %r15
setne %al
testq %rbx, %rbx
setne %cl
testb %cl, %al
movq %r15, %rax
movq %r14, %rdi
movq %r13, %r14
movq %rbx, 0x8(%rsp)
jne 0x3a9a6
movq %r12, 0x10(%rsp)
testq %rbx, %rbx
setne %bl
movq %rax, %r12
testq %rax, %rax
sete 0x7(%rsp)
movq %rdi, %r15
callq 0x37838
movq (%r14), %rcx
movq %r14, %rbp
movq %r14, %rdi
movq %rax, %rsi
callq *0x30(%rcx)
cmpl $0x2, %eax
sete %cl
testl %eax, %eax
setne %al
xorl %r13d, %r13d
testb %cl, 0x7(%rsp)
jne 0x3abc5
orb %al, %bl
movq %r12, %rax
movq 0x10(%rsp), %r12
movq %rbp, %r14
movq %r15, %rdi
je 0x3abc5
cmpl $0x0, 0x3c(%rdi)
jle 0x3aa1e
movq %r12, %rbp
xorl %ebx, %ebx
xorl %r13d, %r13d
movq %rax, %r12
movq %rdi, %r15
movq 0x30(%r15), %rax
movq (%rax,%rbx,8), %rsi
movq (%rbp), %rax
movq %rbp, %rdi
movq %r14, %rdx
movq %r12, %rcx
movq 0x8(%rsp), %r8
callq *0x30(%rax)
orl %eax, %r13d
incq %rbx
movslq 0x3c(%r15), %rax
cmpq %rax, %rbx
jl 0x3a9ba
jmp 0x3abc5
movq %r14, %rdi
callq 0x37838
movq (%r13), %rcx
movq %r13, %rdi
movq %rax, %rsi
callq *0x30(%rcx)
testl %eax, %eax
je 0x3aa26
cmpl $0x2, %eax
jne 0x3aa45
xorl %r13d, %r13d
testq %r15, %r15
je 0x3abc5
movl 0xc(%r15), %edx
movq %r15, %rdi
jmp 0x3aa38
xorl %r13d, %r13d
jmp 0x3abc5
xorl %r13d, %r13d
testq %rbx, %rbx
je 0x3abc5
movl 0xc(%rbx), %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0xaafca
jmp 0x3abc5
movq %rbx, 0x8(%rsp)
leaq 0x28(%rsp), %rdi
callq 0xaaf34
leaq 0x18(%rsp), %rdi
callq 0xaaf34
movq (%r12), %rax
leaq 0x28(%rsp), %rcx
leaq 0x18(%rsp), %r8
movq %r12, %rdi
movq %r14, %rsi
movq %r13, %rdx
callq *0x58(%rax)
testl %eax, %eax
je 0x3ab77
movl $0xd0, %edi
callq 0x134e0
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
callq 0x37448
movl $0xd0, %edi
callq 0x134e0
movq %rax, %rbx
movq %r12, 0x10(%rsp)
movq %r13, %r12
movq %rax, %rdi
xorl %esi, %esi
callq 0x37448
cmpl $0x0, 0x34(%rsp)
jle 0x3aaee
xorl %ebp, %ebp
movq 0x28(%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 0x34(%rsp), %rax
cmpq %rax, %rbp
jl 0x3aabf
cmpl $0x0, 0x24(%rsp)
jle 0x3ab25
xorl %ebp, %ebp
movq 0x18(%rsp), %rax
movq (%rax,%rbp,8), %r13
movq (%r14), %rax
movq %r14, %rdi
movq %r13, %rsi
callq *0x30(%rax)
movq %rbx, %rdi
movq (%rbx), %rax
movq %r13, %rsi
callq *0x28(%rax)
incq %rbp
movslq 0x24(%rsp), %rax
cmpq %rax, %rbp
jl 0x3aaf7
movq 0x10(%rsp), %rbp
movq %rbp, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x39272
movq %rbp, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x39272
testq %r15, %r15
je 0x3ab5a
movl 0xc(%r15), %edx
movq %r15, %rdi
movq %r12, %rsi
callq 0xaafca
movl $0x1, %r13d
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x3abb1
movl 0xc(%rdi), %edx
movq %rbx, %rsi
callq 0xaafca
jmp 0x3abb1
testq %r15, %r15
je 0x3ab92
cmpl $0x0, 0x34(%rsp)
je 0x3ab92
movl 0xc(%r15), %edx
movq %r15, %rdi
movq %r14, %rsi
callq 0xaafca
xorl %r13d, %r13d
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x3abb1
cmpl $0x0, 0x24(%rsp)
je 0x3abb1
movl 0xc(%rdi), %edx
movq %r14, %rsi
callq 0xaafca
leaq 0x18(%rsp), %rdi
callq 0xaaf9e
leaq 0x28(%rsp), %rdi
callq 0xaaf9e
movl %r13d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movl $0xd0, %esi
movq %rbx, %rdi
jmp 0x3abef
movq %rax, %r14
movl $0xd0, %esi
movq %r13, %rdi
callq 0x134f0
jmp 0x3ac06
jmp 0x3ac03
movq %rax, %r14
jmp 0x3ac10
jmp 0x3ac03
jmp 0x3ac03
jmp 0x3ac03
movq %rax, %r14
leaq 0x18(%rsp), %rdi
callq 0xaaf9e
leaq 0x28(%rsp), %rdi
callq 0xaaf9e
movq %r14, %rdi
callq 0x138b0