// File: /workspace/github_cpp_makefile_star2_O3/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, 0x10(%rsp)
movq 0x8(%rdi), %r12
testq %r12, %r12
je 0x22f1b
movl %r9d, %ebp
movq %rcx, %rbx
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %r13
testq %rsi, %rsi
jne 0x22e2c
movq 0x18(%r12), %rax
movq (%rax), %r14
testq %rbx, %rbx
jne 0x22e39
movq 0x18(%r12), %rax
movq (%rax), %rbx
testl %ebp, %ebp
je 0x22e86
movq %r13, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x21f7f
testq %rax, %rax
je 0x22f1b
movq %rax, %r14
movl 0x50(%rsp), %r9d
movq %r13, %rdi
movq %rax, %rsi
movq %rbx, %rdx
movq 0x10(%rsp), %rcx
movl %ebp, %r8d
callq 0x22bfc
movq %rax, %rbx
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
movq %rbx, %rax
jmp 0x22f21
movq %rsp, %r13
movq %r13, %rdi
callq 0xa9ca8
movq (%r12), %rax
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %r13, %rcx
xorl %r8d, %r8d
callq *0x30(%rax)
testl %eax, %eax
je 0x22f13
cmpl $0x0, 0xc(%rsp)
je 0x22f13
movl $0xd0, %edi
callq 0x134e0
movq %rax, %r15
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x3715c
movq %r12, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x38f02
cmpl $0x0, 0xc(%rsp)
jle 0x22f01
xorl %ebx, %ebx
movq (%rsp), %rax
movq (%rax,%rbx,8), %rdi
movq (%rdi), %rax
movq %r15, %rsi
callq *0x20(%rax)
incq %rbx
movslq 0xc(%rsp), %rax
cmpq %rax, %rbx
jl 0x22ee3
movq %r15, %rdi
callq 0x3818c
movq %rsp, %rdi
callq 0xa9d12
jmp 0x22f1e
movq %rsp, %rdi
callq 0xa9d12
xorl %r15d, %r15d
movq %r15, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0xd0, %esi
movq %r15, %rdi
callq 0x134f0
jmp 0x22f47
jmp 0x22f44
movq %rax, %rbx
movq %rsp, %rdi
callq 0xa9d12
movq %rbx, %rdi
callq 0x138b0