// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Scene.cpp
// Function: gaps::R3Scene::ReadPlyFile(char const*, gaps::R3SceneNode*)
int R3Scene::
ReadPlyFile(const char *filename, R3SceneNode *parent_node)
{
  // Check/set parent node
  if (!parent_node) parent_node = root;

  // Read ply file
  R3Mesh mesh;
  if (!mesh.ReadFile(filename)) {
    RNFail("Unable to read mesh %s\n", filename);
    return 0;
  }
  
  // Create array of vertices
  RNArray<R3TriangleVertex *> vertices;
  for (int i = 0; i < mesh.NVertices(); i++) {
    R3MeshVertex *mesh_vertex = mesh.Vertex(i);
    const R3Point& position = mesh.VertexPosition(mesh_vertex);
    R3TriangleVertex *triangle_vertex = new R3TriangleVertex(position);
    if (!mesh.VertexColor(mesh_vertex).IsBlack()) triangle_vertex->SetColor(mesh.VertexColor(mesh_vertex));
    triangle_vertex->SetTextureCoords(mesh.VertexTextureCoords(mesh_vertex));
    triangle_vertex->SetSharedFlag();
    vertices.Insert(triangle_vertex);
  }

  // Check face segments and materials
  int max_face_segment = 0;
  int max_face_material = 0;
  for (int i = 0; i < mesh.NFaces(); i++) {
    R3MeshFace *face = mesh.Face(i);
    int face_segment = mesh.FaceSegment(face);
    int face_material = mesh.FaceMaterial(face);
    if (face_segment > max_face_segment) max_face_segment = face_segment;
    if (face_material > max_face_material) max_face_material = face_material;
  }

  // Create arrays of triangles
  char node_name[1024];
  RNArray<R3Triangle *> *tris_0_0 = NULL;
  RNSymbolTable<RNArray<R3Triangle *> *> triangles;
  for (int i = 0; i < mesh.NFaces(); i++) {
    R3MeshFace *mesh_face = mesh.Face(i);
    int face_segment = mesh.FaceSegment(mesh_face);
    if (face_segment < 0) face_segment = 0;
    int face_category = mesh.FaceCategory(mesh_face);
    if (face_category < 0) face_category = 0;
    int i0 = mesh.VertexID(mesh.VertexOnFace(mesh_face, 0));
    int i1 = mesh.VertexID(mesh.VertexOnFace(mesh_face, 1));
    int i2 = mesh.VertexID(mesh.VertexOnFace(mesh_face, 2));
    R3TriangleVertex *v0 = vertices.Kth(i0);
    R3TriangleVertex *v1 = vertices.Kth(i1);
    R3TriangleVertex *v2 = vertices.Kth(i2);
    R3Triangle *triangle = new R3Triangle(v0, v1, v2);
    RNArray<R3Triangle *> *tris = ((face_segment == 0) && (face_category == 0)) ? tris_0_0 : NULL; 
    if (!tris) {
      sprintf(node_name, "%d_%d", face_category, face_segment);
      if (!triangles.Find(node_name, &tris)) {
        tris = new RNArray<R3Triangle *>();
        if ((face_segment == 0) && (face_category == 0)) tris_0_0 = tris;
        triangles.Insert(node_name, tris);
      }
    }
    tris->Insert(triangle);
  }

  // Create node for each set of triangles
  std::map<std::string, RNArray<R3Triangle *> *, RNMapComparator< std::string > >::iterator it;
  for (it = triangles.m->begin(); it != triangles.m->end(); it++) {
    std::string node_name = it->first;
    RNArray<R3Triangle *> *tris = it->second;
    if (tris->IsEmpty()) { delete tris; continue; }
    R3SceneNode *node = new R3SceneNode(this);
    if (!InsertSceneElement(this, node, NULL, vertices, *tris)) return 0;
    node->SetName(node_name.c_str());
    const char *category_separator = strchr(node_name.c_str(), '_');
    if (category_separator) node->InsertInfo("index", RNStrdup(category_separator+1));
    parent_node->InsertChild(node);
    for (int i = 0; i < tris->NEntries(); i++) delete tris->Kth(i);
    delete tris;
  }

  // Delete vertices 
  for (int i = 0; i < vertices.NEntries(); i++) delete vertices[i];
  
  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x5f8, %rsp            # imm = 0x5F8
movq %rsi, %rbx
movq %rdi, %r15
movq %rdx, 0x40(%rsp)
testq %rdx, %rdx
jne 0x2b5cb
movq (%r15), %rax
movq %rax, 0x40(%rsp)
leaq 0xb8(%rsp), %r14
movq %r14, %rdi
callq 0x4a990
movq %r14, %rdi
movq %rbx, %rsi
callq 0x55e20
testl %eax, %eax
je 0x2b966
movq %r15, 0x70(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x7c1c6
xorl %ebp, %ebp
pushq $0x68
popq %rbx
leaq 0x28(%rsp), %r15
movslq 0xcc(%rsp), %rax
cmpq %rax, %rbp
jge 0x2b677
movq 0xc0(%rsp), %rax
movq (%rax,%rbp,8), %r13
movq %rbx, %rdi
callq 0x218d0
movq %rax, %r12
leaq 0x18(%r13), %rsi
movq %rax, %rdi
callq 0x6098e
leaq 0x58(%r13), %r14
movq %r14, %rdi
callq 0x344c4
testl %eax, %eax
jne 0x2b652
movq %r12, %rdi
movq %r14, %rsi
callq 0x344fa
addq $0x48, %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0x3450e
orb $0x1, 0x5a(%r12)
movq %r15, %rdi
movq %r12, %rsi
callq 0x2737a
incq %rbp
jmp 0x2b607
leaq 0x10(%rsp), %rdi
callq 0x36898
xorl %r13d, %r13d
movq $0x0, 0x18(%rsp)
movslq 0xec(%rsp), %rax
cmpq %rax, %r13
jge 0x2b81d
movq 0xe0(%rsp), %rax
movq %r13, 0x20(%rsp)
movq (%rax,%r13,8), %rax
movl 0x9c(%rax), %ecx
testl %ecx, %ecx
movl $0x0, %r15d
movl %ecx, 0x3c(%rsp)
cmovgl %ecx, %r15d
movl 0xa0(%rax), %ebx
testl %ebx, %ebx
movl $0x0, %ebp
cmovgl %ebx, %ebp
movq 0x8(%rax), %rcx
movq 0x10(%rax), %rdx
movslq 0x70(%rcx), %rcx
movslq 0x70(%rdx), %rdx
movq 0x18(%rax), %rax
movslq 0x70(%rax), %rax
movq 0x28(%rsp), %rsi
movq (%rsi,%rcx,8), %r12
movq (%rsi,%rdx,8), %r14
movq (%rsi,%rax,8), %r13
movl $0x88, %edi
callq 0x218d0
movq %rax, 0x48(%rsp)
movq %rax, %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %r13, %rcx
callq 0x60de0
cmpl $0x0, 0x3c(%rsp)
setle %al
testl %ebx, %ebx
setle %r14b
andb %al, %r14b
movl $0x0, %eax
cmovneq 0x18(%rsp), %rax
movq %rax, 0x50(%rsp)
testq %rax, %rax
jne 0x2b79a
leaq 0x1f0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x9a094(%rip), %rsi     # 0xc57ea
movl %ebp, %edx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x21140
leaq 0x98(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
leaq 0xf(%rsp), %rdx
callq 0x3438a
leaq 0x10(%rsp), %rdi
movq %r15, %rsi
leaq 0x50(%rsp), %rdx
callq 0x34522
movl %eax, %ebp
movq %r15, %rdi
callq 0x213a0
testl %ebp, %ebp
je 0x2b7b6
movq 0x20(%rsp), %r13
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x2737a
incq %r13
jmp 0x2b68d
pushq $0x10
popq %rdi
callq 0x218d0
leaq 0x78(%rsp), %r12
movq 0x20(%rsp), %r13
movq %rax, %r15
movq %rax, %rdi
callq 0x7c1c6
movq %r15, 0x50(%rsp)
testb %r14b, %r14b
movq 0x18(%rsp), %rax
cmovneq %r15, %rax
movq %rax, 0x18(%rsp)
movq %r12, %rdi
leaq 0x1f0(%rsp), %rsi
leaq 0xf(%rsp), %rdx
callq 0x3438a
movq 0x50(%rsp), %rbx
movq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0x36a18
movq %rbx, (%rax)
movq %r12, %rdi
callq 0x213a0
jmp 0x2b79f
movq 0x10(%rsp), %rax
movq 0x18(%rax), %r13
leaq 0x50(%rsp), %r15
pushq $0x10
popq %r12
movq 0x70(%rsp), %r14
addq $0x8, %rax
cmpq %rax, %r13
je 0x2b927
leaq 0x20(%r13), %rsi
movq %r15, %rdi
callq 0x21d00
movq 0x40(%r13), %rbp
cmpl $0x0, 0xc(%rbp)
je 0x2b8f7
movl $0x1b0, %edi            # imm = 0x1B0
callq 0x218d0
movq %rax, %rbx
movq %rax, %rdi
movq %r14, %rsi
callq 0x37a1e
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
leaq 0x28(%rsp), %rcx
movq %rbp, %r8
xorl %r9d, %r9d
callq 0x313e8
movq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0x38b2e
movq 0x50(%rsp), %rdi
pushq $0x5f
popq %rsi
callq 0x21320
testq %rax, %rax
je 0x2b8c7
incq %rax
movq %rax, %rdi
callq 0x7e6a9
movq %rbx, %rdi
leaq 0xa869a(%rip), %rsi     # 0xd3f59
movq %rax, %rdx
callq 0x389f8
movq 0x40(%rsp), %rdi
movq %rbx, %rsi
callq 0x3898c
xorl %ebx, %ebx
movslq 0xc(%rbp), %rax
cmpq %rax, %rbx
jge 0x2b8f7
movq (%rbp), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x2b8f2
movq (%rdi), %rax
callq *0x8(%rax)
incq %rbx
jmp 0x2b8d6
movq %rbp, %rdi
callq 0x7c234
movq %rbp, %rdi
movq %r12, %rsi
callq 0x218f0
movq %r15, %rdi
callq 0x213a0
movq %r13, %rdi
callq 0x21630
movq %rax, %r13
movq 0x10(%rsp), %rax
jmp 0x2b834
xorl %r14d, %r14d
pushq $0x68
popq %rbx
movslq 0x34(%rsp), %rax
cmpq %rax, %r14
jge 0x2b94d
movq 0x28(%rsp), %rax
movq (%rax,%r14,8), %rdi
movq %rbx, %rsi
callq 0x218f0
incq %r14
jmp 0x2b92d
leaq 0x10(%rsp), %rdi
callq 0x3455e
leaq 0x28(%rsp), %rdi
callq 0x7c234
pushq $0x1
popq %rbp
jmp 0x2b979
xorl %ebp, %ebp
leaq 0x99e63(%rip), %rdi     # 0xc57d2
movq %rbx, %rsi
xorl %eax, %eax
callq 0x7e83e
leaq 0xb8(%rsp), %rdi
callq 0x4ae78
movl %ebp, %eax
addq $0x5f8, %rsp            # imm = 0x5F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2ba29
jmp 0x2b9a1
movq %rax, %r14
jmp 0x2ba36
movq %rax, %r14
leaq 0x78(%rsp), %rdi
jmp 0x2ba18
jmp 0x2ba09
movq %rax, %r14
pushq $0x10
popq %rsi
movq %r15, %rdi
jmp 0x2b9f0
movq %rax, %r14
leaq 0x98(%rsp), %rdi
jmp 0x2ba18
jmp 0x2ba09
movq %rax, %r14
movl $0x1b0, %esi            # imm = 0x1B0
movq %rbx, %rdi
callq 0x218f0
jmp 0x2ba13
jmp 0x2ba09
movq %rax, %r14
movl $0x88, %esi
movq 0x48(%rsp), %rdi
callq 0x218f0
jmp 0x2ba1d
jmp 0x2ba09
movq %rax, %r14
pushq $0x68
popq %rsi
movq %r12, %rdi
callq 0x218f0
jmp 0x2ba2c
movq %rax, %r14
jmp 0x2ba1d
jmp 0x2ba10
movq %rax, %r14
leaq 0x50(%rsp), %rdi
callq 0x213a0
leaq 0x10(%rsp), %rdi
callq 0x3455e
jmp 0x2ba2c
movq %rax, %r14
leaq 0x28(%rsp), %rdi
callq 0x7c234
leaq 0xb8(%rsp), %rdi
callq 0x4ae78
movq %r14, %rdi
callq 0x220e0
nop