// File: /workspace/github_cpp_makefile_star2_O1/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 0x23143
movl %r9d, %ebx
movq %rcx, %r14
movq %rdx, %r13
movq %rsi, %r15
movq %rdi, %rbp
testq %rsi, %rsi
jne 0x2305c
movq 0x18(%r12), %rax
movq (%rax), %r15
testq %r14, %r14
jne 0x23069
movq 0x18(%r12), %rax
movq (%rax), %r14
testl %ebx, %ebx
je 0x230b3
movq %rbp, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x22183
movq %rax, %r15
testq %rax, %rax
je 0x2313c
movl 0x50(%rsp), %r9d
movq %rbp, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq 0x10(%rsp), %rcx
movl %ebx, %r8d
callq 0x22e2c
movq %rax, %rbx
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
jmp 0x2313e
movq %rsp, %rbx
movq %rbx, %rdi
callq 0xaaf34
movq (%r12), %rax
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbx, %rcx
xorl %r8d, %r8d
callq *0x30(%rax)
testl %eax, %eax
je 0x23157
cmpl $0x0, 0xc(%rsp)
je 0x23157
movl $0xd0, %edi
callq 0x134e0
movq %rax, %rbx
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x37448
movq %r12, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x39272
cmpl $0x0, 0xc(%rsp)
jle 0x2312f
xorl %r14d, %r14d
movq (%rsp), %rax
movq (%rax,%r14,8), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
callq *0x20(%rax)
incq %r14
movslq 0xc(%rsp), %rax
cmpq %rax, %r14
jl 0x23111
movb $0x1, %r14b
movq %rbx, %rdi
callq 0x384ee
jmp 0x2315c
xorl %ebx, %ebx
testq %r15, %r15
jne 0x23145
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ebx, %ebx
xorl %r14d, %r14d
movq %rsp, %rdi
callq 0xaaf9e
testb %r14b, %r14b
je 0x23143
jmp 0x23145
movq %rax, %r14
movl $0xd0, %esi
movq %rbx, %rdi
callq 0x134f0
jmp 0x23182
jmp 0x2317f
movq %rax, %r14
movq %rsp, %rdi
callq 0xaaf9e
movq %r14, %rdi
callq 0x138b0