// File: tomfunkhouser[P]gaps/apps/sflprocess/sflprocess.cpp
// Function: Mask(gaps::R3SurfelScene*, char const*, gaps::R3SurfelConstraint*)
static int
Mask(R3SurfelScene *scene, const char *node_name, R3SurfelConstraint *constraint)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();

  // Get useful variables
  R3SurfelTree *tree = scene->Tree();
  if (!tree) {
    RNFail("Scene has no surfel tree\n");
    return 0;
  }    

  // Get surfel database
  R3SurfelDatabase *database = tree->Database();
  if (!database) {
    RNFail("Tree has no surfel database\n");
    return 0;
  }    

  // Find node
  R3SurfelNode *node = tree->RootNode();
  if (strcmp(node_name, "All") && strcmp(node_name, "Root")) {
    node = tree->FindNodeByName(node_name);
    if (!node) {
      RNFail("Unable to find node with name %s\n", node_name);
      return 0;
    }
  }

  // Remove surfels not satistfying constraint
  RNArray<R3SurfelNode *> remove_nodes;
  tree->SplitLeafNodes(node, *constraint, NULL, &remove_nodes);
  for (int i = 0; i < remove_nodes.NEntries(); i++) {
    R3SurfelNode *node = remove_nodes.Kth(i);

    // Make array of blocks
    RNArray<R3SurfelBlock *> blocks;
    while (node->NBlocks() > 0) {
      R3SurfelBlock *block = node->Block(0);
      node->RemoveBlock(block);
      blocks.Insert(block);
    }

    // Remove/delete node
    tree->RemoveNode(node);
    delete node;

    // Remove/delete blocks
    for (int j = 0; j < blocks.NEntries(); j++) {
      R3SurfelBlock *block = blocks.Kth(j);
      database->RemoveBlock(block);
      delete block;
    }
  }

  // Return success
  return 1;
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xd8(%rsp)
movq %rsi, 0xd0(%rsp)
movq %rdx, 0xc8(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x16dd30
leaq 0xb8(%rsp), %rdi
callq 0x263f0
movq 0xd8(%rsp), %rdi
callq 0x26780
movq %rax, 0xb0(%rsp)
cmpq $0x0, 0xb0(%rsp)
jne 0x21e57
leaq 0x1d6d1e(%rip), %rdi    # 0x1f8b5e
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xe4(%rsp)
jmp 0x22178
movq 0xb0(%rsp), %rdi
callq 0x26790
movq %rax, 0xa8(%rsp)
cmpq $0x0, 0xa8(%rsp)
jne 0x21e95
leaq 0x1d6cfa(%rip), %rdi    # 0x1f8b78
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xe4(%rsp)
jmp 0x22178
movq 0xb0(%rsp), %rdi
callq 0x276d0
movq %rax, 0xa0(%rsp)
movq 0xd0(%rsp), %rdi
leaq 0x1d6cdc(%rip), %rsi    # 0x1f8b95
callq 0x16a80
cmpl $0x0, %eax
je 0x21f2c
movq 0xd0(%rsp), %rdi
leaq 0x1ddd0c(%rip), %rsi    # 0x1ffbde
callq 0x16a80
cmpl $0x0, %eax
je 0x21f2c
movq 0xb0(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x60280
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0xa0(%rsp)
jne 0x21f2a
movq 0xd0(%rsp), %rsi
leaq 0x1d6c86(%rip), %rdi    # 0x1f8b99
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xe4(%rsp)
jmp 0x22178
jmp 0x21f2c
leaq 0x90(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x276f0
movq 0x48(%rsp), %r8
movq 0xb0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
movq (%rdi), %rax
movq 0x30(%rax), %rax
xorl %ecx, %ecx
callq *%rax
jmp 0x21f68
movl $0x0, 0x80(%rsp)
movl 0x80(%rsp), %eax
movl %eax, 0x44(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x26490
movl %eax, %ecx
movl 0x44(%rsp), %eax
cmpl %ecx, %eax
jge 0x2214f
movl 0x80(%rsp), %esi
leaq 0x90(%rsp), %rdi
callq 0x264a0
movq %rax, 0x38(%rsp)
jmp 0x21fb4
movq 0x38(%rsp), %rax
movq %rax, 0x78(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x27700
jmp 0x21fca
jmp 0x21fcc
movq 0x78(%rsp), %rdi
callq 0x27710
movl %eax, 0x34(%rsp)
jmp 0x21fdc
movl 0x34(%rsp), %eax
cmpl $0x0, %eax
jle 0x2206a
movq 0x78(%rsp), %rdi
xorl %esi, %esi
callq 0x27730
movq %rax, 0x28(%rsp)
jmp 0x21ffc
movq 0x28(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x78(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq (%rdi), %rax
movq 0x30(%rax), %rax
callq *%rax
jmp 0x2201b
movq 0x60(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x27760
jmp 0x2202c
jmp 0x21fcc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
jmp 0x22169
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x277b0
jmp 0x22169
movq 0xb0(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x60330
jmp 0x2207e
movq 0x78(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x22099
movq 0x20(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movl $0x0, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
movl %eax, 0x1c(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x26490
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2212f
movl 0x5c(%rsp), %esi
leaq 0x68(%rsp), %rdi
callq 0x27790
movq %rax, 0x10(%rsp)
jmp 0x220d2
movq 0x10(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0xa8(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0x220f4
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x2211d
movq 0x8(%rsp), %rdi
callq 0x49290
movq 0x8(%rsp), %rdi
movl $0xc8, %esi
callq 0x16750
jmp 0x2211f
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x220a1
leaq 0x68(%rsp), %rdi
callq 0x277b0
movl 0x80(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x80(%rsp)
jmp 0x21f73
movl $0x1, 0xe4(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x277c0
jmp 0x22178
leaq 0x90(%rsp), %rdi
callq 0x277c0
jmp 0x22187
movl 0xe4(%rsp), %eax
addq $0xe8, %rsp
retq
movq 0x88(%rsp), %rdi
callq 0x16ca0
nopw %cs:(%rax,%rax)