// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelTree.cpp
// Function: gaps::R3SurfelTree::SplitBlock(gaps::R3SurfelNode*, gaps::R3SurfelBlock*, gaps::R3SurfelConstraint const&, gaps::R3SurfelBlock**, gaps::R3SurfelBlock**)
int R3SurfelTree::
SplitBlock(R3SurfelNode *node, R3SurfelBlock *block, const R3SurfelConstraint& constraint, 
  R3SurfelBlock **blockA, R3SurfelBlock **blockB)
{
  // Just checking
  assert(node && block);
  assert(block->Node() == node);

  // Check if block is fully outside constraint
  int check = constraint.Check(block);
  if (check == R3_SURFEL_CONSTRAINT_FAIL) { 
    if (blockA) *blockA = NULL;
    if (blockB) *blockB = block;
    return 0;
  }


  // Check if block is fully inside constraint
  if (check == R3_SURFEL_CONSTRAINT_PASS) { 
    if (blockA) *blockA = block;
    if (blockB) *blockB = NULL;
    return 0;
  }

  // Read block
  database->ReadBlock(block);

  // Partition surfels according to constraint
  RNArray<const R3Surfel *> subset1, subset2;
  for (int i = 0; i < block->NSurfels(); i++) {
    const R3Surfel *surfel = block->Surfel(i);
    if (constraint.Check(block, surfel)) subset1.Insert(surfel);
    else subset2.Insert(surfel);
  }

  // Create subset blocks 
  R3SurfelBlock *block1 = NULL;
  R3SurfelBlock *block2 = NULL;
  if (!database->InsertSubsetBlocks(block, subset1, subset2, &block1, &block2) || !block1 || !block2) {
    database->ReleaseBlock(block);
    if (blockA) *blockA = block1;
    if (blockB) *blockB = block2;
    return 0;
  }

  // Update node
  node->InsertBlock(block1); 
  node->InsertBlock(block2); 
  node->RemoveBlock(block);

  // Remove old block
  block->SetDirty(FALSE);
  database->ReleaseBlock(block);
  database->RemoveAndDeleteBlock(block);

  // Return new blocks
  if (blockA) *blockA = block1;
  if (blockB) *blockB = block2;

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r9, %r14
movq %r8, %rbx
movq %rcx, %rbp
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r12
movq (%rcx), %rax
movq %rcx, %rdi
movq %rdx, %rsi
callq *0x20(%rax)
cmpl $0x2, %eax
je 0x3aa36
testl %eax, %eax
jne 0x3aa55
testq %rbx, %rbx
je 0x3aa23
movq $0x0, (%rbx)
xorl %ebx, %ebx
testq %r14, %r14
je 0x3acb4
movq %r15, (%r14)
jmp 0x3acb4
testq %rbx, %rbx
je 0x3aa3e
movq %r15, (%rbx)
xorl %ebx, %ebx
testq %r14, %r14
je 0x3acb4
movq $0x0, (%r14)
jmp 0x3acb4
movl 0xb4(%r15), %eax
testl %eax, %eax
jne 0x3aa83
movq 0x10(%r12), %rdi
movq (%rdi), %rax
movq 0x8(%rdi), %rdx
movl 0x28(%rdi), %ecx
movq %r15, %rsi
callq *0x88(%rax)
testl %eax, %eax
je 0x3aa8c
movl 0xb4(%r15), %eax
incl %eax
movl %eax, 0xb4(%r15)
movq %r13, 0x30(%rsp)
movq %r12, 0x38(%rsp)
movq %rbx, 0x18(%rsp)
movq %r14, 0x40(%rsp)
leaq 0x20(%rsp), %rdi
callq 0xa9ca8
leaq 0x48(%rsp), %r14
movq %r14, %rdi
callq 0xa9ca8
cmpl $0x0, 0x8(%r15)
jle 0x3ab00
xorl %r13d, %r13d
xorl %ebx, %ebx
movq (%r15), %r12
addq %r13, %r12
movq (%rbp), %rax
movq %rbp, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq *0x28(%rax)
movq %r14, %rdi
testl %eax, %eax
je 0x3aae5
leaq 0x20(%rsp), %rdi
movl 0xc(%rdi), %edx
movq %r12, %rsi
callq 0xa9d3e
incq %rbx
movslq 0x8(%r15), %rax
addq $0x30, %r13
cmpq %rax, %rbx
jl 0x3aac3
xorl %eax, %eax
leaq 0x10(%rsp), %r8
movq %rax, (%r8)
leaq 0x8(%rsp), %r9
movq %rax, (%r9)
movq 0x38(%rsp), %r12
movq 0x10(%r12), %rdi
movq (%rdi), %rax
leaq 0x20(%rsp), %rdx
leaq 0x48(%rsp), %rcx
movq %r15, %rsi
callq *0x28(%rax)
movq 0x40(%rsp), %r14
movq 0x30(%rsp), %rbx
testl %eax, %eax
je 0x3ac17
movq 0x10(%rsp), %rsi
testq %rsi, %rsi
je 0x3ac17
cmpq $0x0, 0x8(%rsp)
je 0x3ac17
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x28(%rax)
movq 0x8(%rsp), %rsi
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x28(%rax)
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
callq *0x30(%rax)
movq %r15, %rdi
xorl %esi, %esi
callq 0x2d408
movq 0x10(%r12), %rbx
movl 0xb4(%r15), %eax
cmpl $0x1, %eax
jne 0x3abba
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
movl 0x28(%rbx), %ecx
movq %rbx, %rdi
movq %r15, %rsi
callq *0x90(%rax)
testl %eax, %eax
je 0x3abf0
movl 0xb4(%r15), %eax
decl %eax
movl %eax, 0xb4(%r15)
jne 0x3abf0
testb $0x2, 0x89(%r15)
je 0x3abf0
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
callq *0x18(%rax)
movq %r15, %rdi
callq 0x2ca06
movl $0xc8, %esi
movq %r15, %rdi
callq 0x134f0
movq 0x10(%r12), %rdi
movq (%rdi), %rax
movq %r15, %rsi
callq *0x20(%rax)
movq 0x18(%rsp), %rcx
testq %rcx, %rcx
je 0x3ac10
movq 0x10(%rsp), %rax
movq %rax, (%rcx)
movl $0x1, %ebx
jmp 0x3ac93
movq 0x10(%r12), %rbx
movl 0xb4(%r15), %eax
cmpl $0x1, %eax
jne 0x3ac49
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
movl 0x28(%rbx), %ecx
movq %rbx, %rdi
movq %r15, %rsi
callq *0x90(%rax)
testl %eax, %eax
je 0x3ac7f
movl 0xb4(%r15), %eax
decl %eax
movl %eax, 0xb4(%r15)
jne 0x3ac7f
testb $0x2, 0x89(%r15)
je 0x3ac7f
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
callq *0x18(%rax)
movq %r15, %rdi
callq 0x2ca06
movl $0xc8, %esi
movq %r15, %rdi
callq 0x134f0
movq 0x18(%rsp), %rcx
testq %rcx, %rcx
je 0x3ac91
movq 0x10(%rsp), %rax
movq %rax, (%rcx)
xorl %ebx, %ebx
testq %r14, %r14
je 0x3aca0
movq 0x8(%rsp), %rax
movq %rax, (%r14)
leaq 0x48(%rsp), %rdi
callq 0xa9d12
leaq 0x20(%rsp), %rdi
callq 0xa9d12
movl %ebx, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x3acd9
jmp 0x3accc
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0xa9d12
leaq 0x20(%rsp), %rdi
callq 0xa9d12
movq %rbx, %rdi
callq 0x138b0
nop