// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelUtils.cpp
// Function: gaps::CreateNode(gaps::R3SurfelScene*, gaps::R3SurfelNode*, gaps::R3SurfelConstraint const*, gaps::R3SurfelNode*, char const*, int, int)
R3SurfelNode *
CreateNode(R3SurfelScene *scene, 
  R3SurfelNode *source_node, const R3SurfelConstraint *constraint,
  R3SurfelNode *parent_node, const char *node_name, 
  RNBoolean copy_surfels, RNBoolean release_copied_blocks)
{
  // Initialize result
  R3SurfelNode *node = NULL;

  // Get tree
  R3SurfelTree *tree = scene->Tree();
  if (!tree) return NULL;

  // Get source node
  if (!source_node) source_node = tree->RootNode();

  // Get parent node
  if (!parent_node) parent_node = tree->RootNode();

  // Check if should create copy of surfels for new node
  if (copy_surfels) {
    // Create point set
    R3SurfelPointSet *pointset = CreatePointSet(scene, source_node, constraint);
    if (!pointset) return NULL;
    
    // Create node
    node = CreateNode(scene, pointset, parent_node, node_name,
      copy_surfels, release_copied_blocks);
    
    // Delete point set
    delete pointset;
  }
  else {
    // Get surfel tree
    R3SurfelTree *tree = scene->Tree();
    if (!tree) return NULL;

    // Split leaf nodes
    RNArray<R3SurfelNode *> nodes;
    if (!tree->SplitLeafNodes(source_node, *constraint, &nodes)) return NULL;
    if (nodes.IsEmpty()) return NULL;

    // Create node
    node = new R3SurfelNode(node_name);
    if (!node) return NULL;
    
    // Insert node into tree
    tree->InsertNode(node, parent_node);

    // Move nodes satisfying constraint into node
    for (int i = 0; i < nodes.NEntries(); i++) {
      R3SurfelNode *child = nodes.Kth(i);
      child->SetParent(node); 
    }
    
    // Update properties
    node->UpdateProperties();
  }

  // Return node
  return node;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, (%rsp)
movq 0x8(%rdi), %r12
testq %r12, %r12
je 0x21a70
movl %r9d, %ebp
movq %rcx, %rbx
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %r13
testq %rsi, %rsi
jne 0x21a1b
movq 0x18(%r12), %rax
movq (%rax), %r15
testq %rbx, %rbx
jne 0x21a28
movq 0x18(%r12), %rax
movq (%rax), %rbx
testl %ebp, %ebp
je 0x21a78
movq %r13, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x20cb7
testq %rax, %rax
je 0x21a70
movq %rax, %r14
movl 0x50(%rsp), %r9d
movq %r13, %rdi
movq %rax, %rsi
movq %rbx, %rdx
movq (%rsp), %rcx
movl %ebp, %r8d
callq 0x2186c
movq %rax, %rbx
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
movq %rbx, %rax
jmp 0x21b0a
xorl %r14d, %r14d
jmp 0x21b07
leaq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0x9a7ae
movq (%r12), %rax
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %r13, %rcx
xorl %r8d, %r8d
callq *0x30(%rax)
testl %eax, %eax
je 0x21af0
cmpl $0x0, 0x14(%rsp)
je 0x21af0
movl $0xd0, %edi
callq 0x134f0
movq %rax, %r14
movq %rax, %rdi
movq (%rsp), %rsi
callq 0x33394
movq %r12, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x34e72
xorl %ebx, %ebx
movslq 0x14(%rsp), %rax
cmpq %rax, %rbx
jge 0x21af5
movq 0x8(%rsp), %rax
movq (%rax,%rbx,8), %rdi
movq (%rdi), %rax
movq %r14, %rsi
callq *0x20(%rax)
incq %rbx
jmp 0x21acf
xorl %r14d, %r14d
jmp 0x21afd
movq %r14, %rdi
callq 0x3424a
leaq 0x8(%rsp), %rdi
callq 0x9a81c
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0xd0, %esi
movq %r14, %rdi
callq 0x13500
jmp 0x21b30
jmp 0x21b2d
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x9a81c
movq %rbx, %rdi
callq 0x138f0