// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelTree.cpp
// Function: gaps::R3SurfelTree::SplitBlocks(gaps::R3SurfelNode*, double, double)
int R3SurfelTree::
SplitBlocks(R3SurfelNode *node, RNScalar max_complexity, RNScalar max_extent)
{
  // Just checking
  assert(node);
  assert(node->Tree() == this);
  assert(node->tree_index >= 0);
  assert(nodes.Kth(node->tree_index) == node);
  if ((max_extent <= 0) && (max_complexity <= 0)) return 0;
  int status = 0;
  
  // Make a temporary array of blocks
  RNArray<R3SurfelBlock *> splittable_blocks;
  for (int i = 0; i < node->NBlocks(); i++) {
    R3SurfelBlock *block = node->Block(i);
    splittable_blocks.Insert(block);
  }

  // Split blocks that are too big or have too much complexity
  while (!splittable_blocks.IsEmpty()) {
    R3SurfelBlock *block = splittable_blocks.Tail();
    splittable_blocks.RemoveTail();
    int dim = block->BBox().LongestAxis();
    if (((max_complexity > 0) && (block->NSurfels() > max_complexity)) || 
        ((max_extent > 0) && (block->BBox().AxisLength(dim) > max_extent))) {
      R3SurfelBlock *blockA, *blockB;
      R3Plane split(block->Centroid(), R3xyz_triad[dim]);
      R3SurfelHalfspaceConstraint constraint(R3Halfspace(split, 0));
      if (SplitBlock(node, block, constraint, &blockA, &blockB) && blockA && blockB) {
        splittable_blocks.Insert(blockA);
        splittable_blocks.Insert(blockB);
        status = 1;
      }
    }
  }

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

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x148(%rsp)
movq %rsi, 0x140(%rsp)
movsd %xmm0, 0x138(%rsp)
movsd %xmm1, 0x130(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x50(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x130(%rsp), %xmm0
jb 0x65da2
xorps %xmm0, %xmm0
ucomisd 0x138(%rsp), %xmm0
jb 0x65da2
movl $0x0, 0x154(%rsp)
jmp 0x660d7
movl $0x0, 0x12c(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x436b0
movl $0x0, 0x114(%rsp)
movl 0x114(%rsp), %eax
movl %eax, 0x48(%rsp)
movq 0x140(%rsp), %rdi
callq 0x186b0
movl %eax, 0x4c(%rsp)
jmp 0x65de3
movl 0x48(%rsp), %eax
movl 0x4c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x65e5c
movq 0x140(%rsp), %rdi
movl 0x114(%rsp), %esi
callq 0x186d0
movq %rax, 0x40(%rsp)
jmp 0x65e0a
movq 0x40(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x436c0
jmp 0x65e2e
jmp 0x65e30
movl 0x114(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x114(%rsp)
jmp 0x65dc5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x660c8
jmp 0x65e5e
leaq 0x118(%rsp), %rdi
callq 0x31da0
movl %eax, 0x3c(%rsp)
jmp 0x65e71
movl 0x3c(%rsp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x65e86
jmp 0x660ab
leaq 0x118(%rsp), %rdi
callq 0x66330
movq %rax, 0x30(%rsp)
jmp 0x65e9a
movq 0x30(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x1c0c0
jmp 0x65eb6
movq 0xf0(%rsp), %rdi
callq 0x4a500
movq %rax, 0x28(%rsp)
jmp 0x65eca
movq 0x28(%rsp), %rdi
callq 0xcb070
movl %eax, 0x24(%rsp)
jmp 0x65eda
movl 0x24(%rsp), %eax
movl %eax, 0xec(%rsp)
movsd 0x138(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x65f1d
movq 0xf0(%rsp), %rdi
callq 0x1c0e0
movl %eax, 0x20(%rsp)
jmp 0x65f0a
movl 0x20(%rsp), %eax
cvtsi2sd %eax, %xmm0
ucomisd 0x138(%rsp), %xmm0
ja 0x65f75
movsd 0x130(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x660a6
movq 0xf0(%rsp), %rdi
callq 0x4a500
movq %rax, 0x18(%rsp)
jmp 0x65f47
movq 0x18(%rsp), %rdi
movl 0xec(%rsp), %esi
callq 0x456f0
movsd %xmm0, 0x10(%rsp)
jmp 0x65f60
movsd 0x10(%rsp), %xmm0
ucomisd 0x130(%rsp), %xmm0
jbe 0x660a6
movq 0xf0(%rsp), %rsi
leaq 0xa0(%rsp), %rdi
callq 0x66340
jmp 0x65f8c
movl 0xec(%rsp), %esi
leaq 0x19768e(%rip), %rdi    # 0x1fd628
callq 0x44220
movq %rax, 0x8(%rsp)
jmp 0x65fa6
movq 0x8(%rsp), %rdx
leaq 0xb8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0xf5ab0
jmp 0x65fc2
leaq 0x58(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
xorl %edx, %edx
callq 0xf58a0
jmp 0x65fd8
leaq 0x78(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x51450
jmp 0x65fe9
movq 0x50(%rsp), %rdi
movq 0x140(%rsp), %rsi
movq 0xf0(%rsp), %rdx
movq (%rdi), %rax
movq 0x50(%rax), %rax
leaq 0x78(%rsp), %rcx
leaq 0xe0(%rsp), %r8
leaq 0xd8(%rsp), %r9
callq *%rax
movl %eax, 0x4(%rsp)
jmp 0x66022
movl 0x4(%rsp), %eax
cmpl $0x0, %eax
je 0x6609c
cmpq $0x0, 0xe0(%rsp)
je 0x6609c
cmpq $0x0, 0xd8(%rsp)
je 0x6609c
movq 0xe0(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x436c0
jmp 0x66058
movq 0xd8(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x436c0
jmp 0x6606f
movl $0x1, 0x12c(%rsp)
jmp 0x6609c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x54fc0
jmp 0x660c8
leaq 0x78(%rsp), %rdi
callq 0x54fc0
jmp 0x65e5e
movl 0x12c(%rsp), %eax
movl %eax, 0x154(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x43730
jmp 0x660d7
leaq 0x118(%rsp), %rdi
callq 0x43730
jmp 0x660e6
movl 0x154(%rsp), %eax
addq $0x158, %rsp            # imm = 0x158
retq
movq 0x108(%rsp), %rdi
callq 0x13970
nopw %cs:(%rax,%rax)