// File: /workspace/github_cpp_makefile_star2_O1/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::ReadPlyStream(_IO_FILE*)
int R3Mesh::
ReadPlyStream(FILE *fp)
{
  int i,j;
  PlyFile *ply;
  int nelems;
  PlyProperty **plist;
  char **elist;
  int file_type;
  int nprops;
  int num_elems;
  char *elem_name;
  float version;
  int num_rows = 0;
  int num_cols = 0;

  typedef struct PlyVertex {
    float x, y, z;
    float nx, ny, nz;
    float tx, ty;
    unsigned char red, green, blue;
  } PlyVertex;

  typedef struct PlyFace {
    unsigned char nverts;
    int *verts;
    int material;
    int segment;
    int category;
  } PlyFace;

  typedef struct PlyRangeGrid {
    unsigned char nverts;
    int *verts;
  } PlyRangeGrid;

  // List of property information for a vertex 
  static PlyProperty vert_props[] = { 
    {(char *) "x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,x), 0, 0, 0, 0},
    {(char *) "y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,y), 0, 0, 0, 0},
    {(char *) "z", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,z), 0, 0, 0, 0},
    {(char *) "nx", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nx), 0, 0, 0, 0},
    {(char *) "ny", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,ny), 0, 0, 0, 0},
    {(char *) "nz", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nz), 0, 0, 0, 0},
    {(char *) "tx", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,tx), 0, 0, 0, 0},
    {(char *) "ty", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,ty), 0, 0, 0, 0},
    {(char *) "red", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,red), 0, 0, 0, 0},
    {(char *) "green", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,green), 0, 0, 0, 0},
    {(char *) "blue", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,blue), 0, 0, 0, 0}
  };

  // List of property information for a face 
  static PlyProperty face_props[] = { 
    {(char *) "vertex_indices", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
    {(char *) "vertex_index", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
    {(char *) "material_id", PLY_INT, PLY_INT, offsetof(PlyFace,material), 0, 0, 0, 0},
    {(char *) "segment_id", PLY_INT, PLY_INT, offsetof(PlyFace,segment), 0, 0, 0, 0},
    {(char *) "category_id", PLY_INT, PLY_INT, offsetof(PlyFace,category), 0, 0, 0, 0}
  };

  // List of property information for a range_grid
  static PlyProperty range_grid_props[] = { 
    {(char *) "vertex_indices", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
  };

  // Read PLY header
  ply = ply_read (fp, &nelems, &elist);
  if (!ply) {
    RNFail("Unable to read ply file header");
    fclose(fp);
    return 0;
  }
  
  // Get header info
  ply_get_info (ply, &version, &file_type);

  // Read all elements
  for (i = 0; i < nelems; i++) {
    // Get the description of the element 
    elem_name = elist[i];
    plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);

    // Check element type
    if (equal_strings ("vertex", elem_name)) {
      // Allocate block of vertices
      vertex_block = new R3MeshVertex [num_elems];

      // Resize array of vertices
      vertices.Resize(num_elems);

      // set up for getting vertex elements 
      RNBoolean has_normals = 0;
      RNBoolean has_texcoords = 0;
      RNBoolean has_colors = 0;
      for (j = 0; j < nprops; j++) {
	if (equal_strings("x", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[0]);
	else if (equal_strings("y", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[1]);
	else if (equal_strings("z", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[2]);
	else if (equal_strings("nx", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[3]); 
	else if (equal_strings("ny", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[4]); 
	else if (equal_strings("nz", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[5]);
	else if (equal_strings("tx", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[6]); 
	else if (equal_strings("ty", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[7]); 
	else if (equal_strings("red", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[8]); 
	else if (equal_strings("green", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[9]); 
	else if (equal_strings("blue", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[10]);
	if (equal_strings("nx", plist[j]->name)) has_normals = 1;
	else if (equal_strings("tx", plist[j]->name)) has_texcoords = 1;
	else if (equal_strings("red", plist[j]->name)) has_colors = 1;
      }

      // grab all the vertex elements 
      for (j = 0; j < num_elems; j++) {
        // Read vertex into local struct
        PlyVertex plyvertex;
        ply_get_element(ply, (void *) &plyvertex);

        // Create mesh vertex
        R3Point position(plyvertex.x, plyvertex.y, plyvertex.z);
        R3MeshVertex *v = CreateVertex(position, &vertex_block[j]);
        if (has_normals) {
          R3Vector normal(plyvertex.nx, plyvertex.ny, plyvertex.nz);
          SetVertexNormal(v, normal);
        }
        if (has_texcoords) {
          R2Point texcoords(plyvertex.tx, plyvertex.ty);
          SetVertexTextureCoords(v, texcoords);
        }
        if (has_colors) {
          RNRgb color(plyvertex.red/255.0, plyvertex.green/255.0, plyvertex.blue/255.0);
          SetVertexColor(v, color);
        }
      }
    }
    else if (equal_strings ("face", elem_name)) {
      // Resize array of faces
      faces.Resize(num_elems);

      // set up for getting face elements 
      for (j = 0; j < nprops; j++) {
	if (equal_strings("vertex_indices", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[0]);
	else if (equal_strings("vertex_index", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[1]);
	else if (equal_strings("material_id", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[2]);
	else if (equal_strings("segment_id", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[3]);
	else if (equal_strings("category_id", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[4]);
      }

      // Create stuff for degenerate triangles
      RNArray<R3MeshVertex *> degenerate_triangle_vertices;
      int *degenerate_triangle_materials = new int [ num_elems ];
      int *degenerate_triangle_segments = new int [ num_elems ];
      int *degenerate_triangle_categories = new int [ num_elems ];
      int num_degenerate_triangles = 0;

      // grab all the face elements 
      for (j = 0; j < num_elems; j++) {
        // Read face into local struct
        PlyFace plyface;
        plyface.nverts = 0;
        plyface.verts = NULL;
        plyface.material = -1;
        plyface.segment = -1;
        plyface.category = -1;
        ply_get_element(ply, (void *) &plyface);

        // Create mesh face(s)
        R3MeshVertex *v1 = vertices[plyface.verts[0]];
        for (int k = 2; k < plyface.nverts; k++) {
          // Get vertices
          R3MeshVertex *v2 = vertices[plyface.verts[k-1]];
          R3MeshVertex *v3 = vertices[plyface.verts[k]];

          // Check plyface
          assert(plyface.verts[0] >= 0);
          assert(plyface.verts[k-1] >= 0);
          assert(plyface.verts[k] >= 0);
          assert(plyface.verts[0] < vertices.NEntries());
          assert(plyface.verts[k-1] < vertices.NEntries());
          assert(plyface.verts[k] < vertices.NEntries());

          // Check vertices
          if ((v1 == v2) || (v2 == v3) || (v1 == v3)) continue;

          // Create face
          R3MeshFace *f = CreateFace(v1, v2, v3);
          if (f) {
            // Set material/segment/category
            SetFaceMaterial(f, plyface.material);
            SetFaceSegment(f, plyface.segment);
            SetFaceCategory(f, plyface.category);
          }
          else {
            // Must have been degeneracy (e.g., three faces sharing an edge)
            // Remember for later processing (to preserve vertex indices)
            degenerate_triangle_vertices.Insert(v1);
            degenerate_triangle_vertices.Insert(v2);
            degenerate_triangle_vertices.Insert(v3);
            degenerate_triangle_materials[num_degenerate_triangles] = plyface.material;
            degenerate_triangle_segments[num_degenerate_triangles] = plyface.segment;
            degenerate_triangle_categories[num_degenerate_triangles] = plyface.category;
            num_degenerate_triangles++;
          }
        }

        // Free face data allocated by ply
        if (plyface.verts) free(plyface.verts);
      }
      
      // Create degenerate triangles (do this at end to preserve face ordering)
      for (int i = 0; i < num_degenerate_triangles; i++) {
        R3MeshVertex *v1 = degenerate_triangle_vertices.Kth(3*i + 0);
        R3MeshVertex *v2 = degenerate_triangle_vertices.Kth(3*i + 1);
        R3MeshVertex *v3 = degenerate_triangle_vertices.Kth(3*i + 2);
        R3MeshFace *f = CreateFace(v1, v2, v3);
        if (!f) {
          f = CreateFace(v1, v3, v2);
          if (!f) {
            // Note: these vertices are allocated separately, and so they will not be deleted (memory leak)
            R3MeshVertex *v1a = CreateVertex(VertexPosition(v1));
            R3MeshVertex *v2a = CreateVertex(VertexPosition(v2));
            R3MeshVertex *v3a = CreateVertex(VertexPosition(v3));
            f = CreateFace(v1a, v2a, v3a);
          }
        }
        if (f) {
          SetFaceMaterial(f, degenerate_triangle_materials[i]);
          SetFaceSegment(f, degenerate_triangle_segments[i]);
          SetFaceCategory(f, degenerate_triangle_categories[i]);
        }
      }

      // Delete memory for degenerate triangles
      delete [] degenerate_triangle_materials;
      delete [] degenerate_triangle_segments;
      delete [] degenerate_triangle_categories;
    }
    else if (equal_strings ("range_grid", elem_name)) {
      // Get num_cols and num_rows for range_grid
      int ninfo = 0;
      char **info = ply_get_obj_info(ply, &ninfo);
      for (int i = 0; i < ninfo; i++) {
        char *str = RNStrdup(info[i]);
        char *strp = strtok(str, " \n\t");
        if (strp) {
          if (!strcmp(strp, "num_rows")) {
            strp = strtok(NULL, " \n\t");
            if (strp) num_rows = atoi(strp);
          }
          else if (!strcmp(strp, "num_cols")) {
            strp = strtok(NULL, " \n\t");
            if (strp) num_cols = atoi(strp);
          }
        }
        free(str);
      }

      // check num_cols and num_rows
      if ((num_cols > 0) && (num_rows > 0) && (num_cols * num_rows == num_elems)) {
        // Allocate vertex grid
        R3MeshVertex **vertex_grid = new R3MeshVertex * [num_elems];
        for (j = 0; j < num_elems; j++) vertex_grid[j] = NULL;

        // set up for getting range grid elements 
        for (j = 0; j < nprops; j++) {
          if (equal_strings("vertex_indices", plist[j]->name)) ply_get_property (ply, elem_name, &range_grid_props[0]);
        }

        // grab all the range grid vertices
        for (j = 0; j < num_elems; j++) {
          // Read face into local struct
          PlyRangeGrid ply_range_grid;
          ply_range_grid.nverts = 0;
          ply_range_grid.verts = NULL;
          ply_get_element(ply, (void *) &ply_range_grid);
          if (!ply_range_grid.verts) continue;
          if (ply_range_grid.nverts == 0) continue;
          vertex_grid[j] = vertices[ply_range_grid.verts[0]];
          free(ply_range_grid.verts);
        }

        // create faces
        for (int row = 0; row < num_rows-1; row++) {
          for (int col = 0; col < num_cols-1; col++) {
            R3MeshVertex *v00 = vertex_grid[(row)*num_cols + (col)];
            R3MeshVertex *v01 = vertex_grid[(row+1)*num_cols + (col)];
            R3MeshVertex *v10 = vertex_grid[(row)*num_cols + (col+1)];
            R3MeshVertex *v11 = vertex_grid[(row+1)*num_cols + (col+1)];
            if (v00) {
              if (v01) {
                if (v10) {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v00, v10, v11);
                    CreatePlyRangeGridFace(this, v00, v11, v01);
                  }
                  else {
                    CreatePlyRangeGridFace(this, v00, v10, v01);
                  }
                }
                else {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v00, v11, v01);
                  }
                }
              }
              else {
                if (v10) {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v00, v10, v11);
                  }
                }
              }
            }
            else {
              if (v01) {
                if (v10) {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v10, v11, v01);
                  }
                }
              }
            }
          }
        }

        // Delete vertex grid
        delete [] vertex_grid;
      }
    }
    else {
      ply_get_other_element (ply, elem_name, num_elems);
    }
  }

  // Free the memory
  free(ply);

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rsi, %r14
movq %rdi, %r15
leaq 0x7c(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
movq %r14, %rdi
callq 0x3f0e5
testq %rax, %rax
je 0x20ba6
movq %rax, %r12
leaq 0xc8(%rsp), %rsi
leaq 0xcc(%rsp), %rdx
movq %rax, %rdi
callq 0x404f5
cmpl $0x0, 0x7c(%rsp)
jle 0x20b97
leaq 0x8(%r15), %rax
movq %rax, 0xb8(%rsp)
leaq 0x28(%r15), %rax
movq %rax, 0xb0(%rsp)
xorl %r13d, %r13d
leaq 0xc568f(%rip), %rbp     # 0xe5680
movq $0x0, 0x60(%rsp)
movq $0x0, 0x68(%rsp)
movq %r12, 0x30(%rsp)
movq %r15, 0x10(%rsp)
movq 0xc0(%rsp), %rax
movq (%rax,%r13,8), %r14
movq %r12, %rdi
movq %r14, %rsi
leaq 0xc(%rsp), %rdx
leaq 0x1c(%rsp), %rcx
callq 0x3f956
movq %rax, %r15
leaq 0x8260a(%rip), %rdi     # 0xa2642
movq %r14, %rsi
callq 0x3f6ab
testl %eax, %eax
movq %r13, 0x80(%rsp)
je 0x202ef
movq %r14, 0x20(%rsp)
movslq 0xc(%rsp), %r14
movq %r14, %rax
movl $0x98, %ecx
mulq %rcx
movq %rax, %r13
seto %al
addq $0x8, %r13
movq $-0x1, %rcx
cmovbq %rcx, %r13
testb %al, %al
cmovneq %rcx, %r13
movq %r13, %rdi
callq 0xe030
movq %rax, %rbp
addq $0x8, %rax
movq %rax, 0x28(%rsp)
movq %r14, (%rbp)
testq %r14, %r14
je 0x200c6
imulq $-0x98, %r14, %r12
movq 0x28(%rsp), %r14
xorl %ebx, %ebx
movq %r14, %rdi
callq 0x23c38
addq $-0x98, %rbx
addq $0x98, %r14
cmpq %rbx, %r12
jne 0x200ab
movq 0x10(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x38(%rax)
movl 0xc(%rsp), %esi
movq 0xb8(%rsp), %rdi
callq 0x706e0
cmpl $0x0, 0x1c(%rsp)
jle 0x20595
xorl %r14d, %r14d
xorl %r13d, %r13d
xorl %ebx, %ebx
xorl %ebp, %ebp
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8b0ea(%rip), %rdi     # 0xab1f2
callq 0x3f6ab
leaq 0xc53ac(%rip), %rdx     # 0xe54c0
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82240(%rip), %rdi     # 0xa236a
callq 0x3f6ab
leaq 0xc53b2(%rip), %rdx     # 0xe54e8
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82484(%rip), %rdi     # 0xa25d0
callq 0x3f6ab
leaq 0xc53b8(%rip), %rdx     # 0xe5510
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8245b(%rip), %rdi     # 0xa25c9
callq 0x3f6ab
leaq 0xc53be(%rip), %rdx     # 0xe5538
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8243c(%rip), %rdi     # 0xa25cc
callq 0x3f6ab
leaq 0xc53c4(%rip), %rdx     # 0xe5560
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8241d(%rip), %rdi     # 0xa25cf
callq 0x3f6ab
leaq 0xc53ca(%rip), %rdx     # 0xe5588
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x823fe(%rip), %rdi     # 0xa25d2
callq 0x3f6ab
leaq 0xc53d0(%rip), %rdx     # 0xe55b0
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x889a0(%rip), %rdi     # 0xa8b92
callq 0x3f6ab
leaq 0xc53da(%rip), %rdx     # 0xe55d8
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x823c5(%rip), %rdi     # 0xa25d5
callq 0x3f6ab
leaq 0xc53e4(%rip), %rdx     # 0xe5600
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x823ab(%rip), %rdi     # 0xa25d9
callq 0x3f6ab
leaq 0xc53ee(%rip), %rdx     # 0xe5628
testl %eax, %eax
jne 0x2025c
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82393(%rip), %rdi     # 0xa25df
callq 0x3f6ab
leaq 0xc53f8(%rip), %rdx     # 0xe5650
testl %eax, %eax
je 0x2026b
movq 0x30(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x3faf9
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82350(%rip), %rdi     # 0xa25c9
callq 0x3f6ab
testl %eax, %eax
je 0x2028a
movl $0x1, %r13d
jmp 0x202c5
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8233a(%rip), %rdi     # 0xa25d2
callq 0x3f6ab
testl %eax, %eax
je 0x202a8
movl $0x1, %ebx
jmp 0x202c5
movq (%r15,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8231f(%rip), %rdi     # 0xa25d5
callq 0x3f6ab
testl %eax, %eax
movl $0x1, %eax
cmovnel %eax, %ebp
incq %r14
movslq 0x1c(%rsp), %rax
cmpq %rax, %r14
jl 0x200fa
testl %r13d, %r13d
sete 0x20(%rsp)
testl %ebx, %ebx
sete %r12b
testl %ebp, %ebp
sete %bpl
jmp 0x205a0
leaq 0x82353(%rip), %rdi     # 0xa2649
movq %r14, %rsi
callq 0x3f6ab
testl %eax, %eax
je 0x206f9
movl 0xc(%rsp), %esi
movq 0xb0(%rsp), %rdi
callq 0x706e0
cmpl $0x0, 0x1c(%rsp)
jle 0x203d2
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x822b2(%rip), %rdi     # 0xa25e4
callq 0x3f6ab
movq %rbp, %rdx
testl %eax, %eax
jne 0x203b6
movq (%r15,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x822a7(%rip), %rdi     # 0xa25f3
callq 0x3f6ab
leaq 0xc5350(%rip), %rdx     # 0xe56a8
testl %eax, %eax
jne 0x203b6
movq (%r15,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x82296(%rip), %rdi     # 0xa2600
callq 0x3f6ab
leaq 0xc535a(%rip), %rdx     # 0xe56d0
testl %eax, %eax
jne 0x203b6
movq (%r15,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x82284(%rip), %rdi     # 0xa260c
callq 0x3f6ab
leaq 0xc5364(%rip), %rdx     # 0xe56f8
testl %eax, %eax
jne 0x203b6
movq (%r15,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x82271(%rip), %rdi     # 0xa2617
callq 0x3f6ab
leaq 0xc536e(%rip), %rdx     # 0xe5720
testl %eax, %eax
je 0x203c1
movq %r12, %rdi
movq %r14, %rsi
callq 0x3faf9
incq %rbx
movslq 0x1c(%rsp), %rax
cmpq %rax, %rbx
jl 0x20324
leaq 0x88(%rsp), %rdi
callq 0x705ec
movslq 0xc(%rsp), %rax
leaq (,%rax,4), %r14
testq %rax, %rax
movq $-0x1, %rax
cmovsq %rax, %r14
movq %r14, %rdi
callq 0xe030
movq %rax, 0x20(%rsp)
movq %r14, %rdi
callq 0xe030
movq %rax, 0x28(%rsp)
movq 0x10(%rsp), %r15
movq %r14, %rdi
callq 0xe030
movq %rax, 0x70(%rsp)
cmpl $0x0, 0xc(%rsp)
jle 0x20a26
xorl %ebp, %ebp
xorl %r12d, %r12d
movb $0x0, 0x38(%rsp)
movq $0x0, 0x40(%rsp)
movq $-0x1, 0x48(%rsp)
movl $0xffffffff, 0x50(%rsp) # imm = 0xFFFFFFFF
movq 0x30(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x3fb81
cmpb $0x3, 0x38(%rsp)
jb 0x20575
movq 0x40(%rsp), %rax
movslq (%rax), %rax
movq 0x8(%r15), %rcx
movq (%rcx,%rax,8), %r13
movl $0x2, %ebx
movq 0x40(%rsp), %rax
movslq -0x4(%rax,%rbx,4), %rdx
movq 0x8(%r15), %rcx
movq (%rcx,%rdx,8), %r15
cmpq %r15, %r13
je 0x2055f
movslq (%rax,%rbx,4), %rax
movq (%rcx,%rax,8), %r14
cmpq %r14, %r15
je 0x2055f
cmpq %r14, %r13
je 0x2055f
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
movq %r13, %rsi
movq %r15, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
je 0x204ed
movq 0x48(%rsp), %rcx
movq %rcx, 0x98(%rax)
movl 0x50(%rsp), %ecx
movl %ecx, 0xa0(%rax)
jmp 0x2055f
movl 0x94(%rsp), %edx
leaq 0x88(%rsp), %rdi
movq %r13, %rsi
callq 0x70682
movl 0x94(%rsp), %edx
leaq 0x88(%rsp), %rdi
movq %r15, %rsi
callq 0x70682
movl 0x94(%rsp), %edx
leaq 0x88(%rsp), %rdi
movq %r14, %rsi
callq 0x70682
movl 0x48(%rsp), %eax
movslq %r12d, %r12
movq 0x20(%rsp), %rcx
movl %eax, (%rcx,%r12,4)
movl 0x4c(%rsp), %eax
movq 0x28(%rsp), %rcx
movl %eax, (%rcx,%r12,4)
movl 0x50(%rsp), %eax
movq 0x70(%rsp), %rcx
movl %eax, (%rcx,%r12,4)
incl %r12d
incq %rbx
movzbl 0x38(%rsp), %eax
cmpq %rax, %rbx
movq 0x10(%rsp), %r15
jb 0x20484
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x20584
callq 0xe540
incl %ebp
cmpl 0xc(%rsp), %ebp
jl 0x20436
jmp 0x20a29
movb $0x1, %bpl
movb $0x1, %r12b
movb $0x1, 0x20(%rsp)
cmpl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %r15
jle 0x20b5f
xorl %r13d, %r13d
xorl %ebx, %ebx
movq 0x30(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x3fb81
xorps %xmm0, %xmm0
cvtss2sd 0x38(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x3c(%rsp), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x40(%rsp), %xmm2
leaq 0x88(%rsp), %r14
movq %r14, %rdi
callq 0x3ca26
movq 0x38(%r15), %rdx
addq %r13, %rdx
movq (%r15), %rax
movq %r15, %rdi
movq %r14, %rsi
callq *0x20(%rax)
movq %rax, %r15
cmpb $0x0, 0x20(%rsp)
jne 0x20648
xorps %xmm0, %xmm0
cvtss2sd 0x44(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x48(%rsp), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x4c(%rsp), %xmm2
leaq 0xd0(%rsp), %r14
movq %r14, %rdi
callq 0x3d4be
leaq 0x30(%r15), %rdi
movq %r14, %rsi
callq 0x3dc6a
orb $0x2, 0x78(%r15)
testb %r12b, %r12b
jne 0x2067b
xorps %xmm0, %xmm0
cvtss2sd 0x50(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x54(%rsp), %xmm1
leaq 0xd0(%rsp), %r14
movq %r14, %rdi
callq 0x68e2e
leaq 0x48(%r15), %rdi
movq %r14, %rsi
callq 0x68f66
testb %bpl, %bpl
jne 0x206d7
movzbl 0x58(%rsp), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x81b84(%rip), %xmm3    # 0xa2218
divsd %xmm3, %xmm0
movzbl 0x59(%rsp), %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
divsd %xmm3, %xmm1
movzbl 0x5a(%rsp), %eax
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
divsd %xmm3, %xmm2
leaq 0xd0(%rsp), %r14
movq %r14, %rdi
callq 0x70460
addq $0x58, %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x704f2
incq %rbx
movslq 0xc(%rsp), %rax
addq $0x98, %r13
cmpq %rax, %rbx
movq 0x10(%rsp), %r15
jl 0x205b5
jmp 0x20b5f
leaq 0x81f4e(%rip), %rdi     # 0xa264e
movq %r14, %rsi
callq 0x3f6ab
testl %eax, %eax
je 0x20b86
movq %r14, 0x20(%rsp)
movl $0x0, 0x88(%rsp)
movq %r12, %rdi
leaq 0x88(%rsp), %rsi
callq 0x4006a
movq %rax, 0x28(%rsp)
cmpl $0x0, 0x88(%rsp)
jle 0x207ef
xorl %ebp, %ebp
leaq 0x81f0d(%rip), %rbx     # 0xa2659
leaq 0x81f0a(%rip), %r12     # 0xa265d
movq 0x28(%rsp), %rax
movq (%rax,%rbp,8), %rdi
callq 0x7287b
movq %rax, %r13
movq %rax, %rdi
movq %rbx, %rsi
callq 0xe710
testq %rax, %rax
je 0x207d3
movq %rax, %r14
movq %rax, %rdi
movq %r12, %rsi
callq 0xe640
testl %eax, %eax
je 0x207b7
movq %r14, %rdi
leaq 0x81ed6(%rip), %rsi     # 0xa2666
callq 0xe640
testl %eax, %eax
jne 0x207d3
xorl %edi, %edi
movq %rbx, %rsi
callq 0xe710
testq %rax, %rax
je 0x207d3
movq %rax, %rdi
callq 0xe700
movq %rax, 0x68(%rsp)
jmp 0x207d3
xorl %edi, %edi
movq %rbx, %rsi
callq 0xe710
testq %rax, %rax
je 0x207d3
movq %rax, %rdi
callq 0xe700
movq %rax, 0x60(%rsp)
movq %r13, %rdi
callq 0xe540
incq %rbp
movslq 0x88(%rsp), %rax
cmpq %rax, %rbp
jl 0x20753
cmpl $0x0, 0x68(%rsp)
jle 0x20b5f
cmpl $0x0, 0x60(%rsp)
jle 0x20b5f
movq 0x60(%rsp), %rax
imull 0x68(%rsp), %eax
movl 0xc(%rsp), %r14d
cmpl %r14d, %eax
jne 0x20b5f
movl %r14d, %ebx
shlq $0x3, %r14
movq %r14, %rdi
callq 0xe030
movq %rax, %rbp
testl %ebx, %ebx
movq 0x30(%rsp), %r12
leaq 0x81da7(%rip), %r13     # 0xa25e4
jle 0x2084c
movq %rbp, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0xe260
movq %rbp, 0xa0(%rsp)
cmpl $0x0, 0x1c(%rsp)
leaq 0xc4ef0(%rip), %r14     # 0xe5750
movq 0x20(%rsp), %rbp
jle 0x20897
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rax
movq (%rax), %rsi
movq %r13, %rdi
callq 0x3f6ab
testl %eax, %eax
je 0x2088a
movq %r12, %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0x3faf9
incq %rbx
movslq 0x1c(%rsp), %rax
cmpq %rax, %rbx
jl 0x20869
cmpl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %r14
movq 0xa0(%rsp), %r15
jle 0x208fa
xorl %ebx, %ebx
movb $0x0, 0x38(%rsp)
movq $0x0, 0x40(%rsp)
movq %r12, %rdi
leaq 0x38(%rsp), %rsi
callq 0x3fb81
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x208ed
cmpb $0x0, 0x38(%rsp)
je 0x208ed
movslq (%rdi), %rax
movq 0x8(%r14), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, (%r15,%rbx,8)
callq 0xe540
incq %rbx
movslq 0xc(%rsp), %rax
cmpq %rax, %rbx
jl 0x208ad
cmpl $0x2, 0x60(%rsp)
jl 0x20a14
movq 0x60(%rsp), %rax
decl %eax
movq %rax, 0x70(%rsp)
movq 0x68(%rsp), %rax
leal -0x1(%rax), %ecx
movq %rcx, 0x20(%rsp)
movl %eax, %eax
movq 0xa0(%rsp), %rbp
leaq 0x8(,%rax,8), %r13
addq %rbp, %r13
shlq $0x3, %rax
movq %rax, 0xa8(%rsp)
addq $0x8, %rbp
xorl %ecx, %ecx
movq %rcx, 0x28(%rsp)
cmpl $0x2, 0x68(%rsp)
jl 0x209f3
xorl %ebx, %ebx
movq -0x8(%rbp,%rbx,8), %r14
movq (%rbp,%rbx,8), %rdx
movq -0x8(%r13,%rbx,8), %r12
movq (%r13,%rbx,8), %r15
testq %r14, %r14
je 0x20991
testq %r12, %r12
je 0x209aa
testq %rdx, %rdx
je 0x209c1
testq %r15, %r15
je 0x209e9
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movq %r15, %rcx
callq 0x20c3d
jmp 0x209c6
testq %r12, %r12
je 0x209d9
testq %rdx, %rdx
je 0x209d9
testq %r15, %r15
je 0x209d9
movq 0x10(%rsp), %rdi
movq %rdx, %rsi
jmp 0x209ce
testq %rdx, %rdx
je 0x209d9
testq %r15, %r15
je 0x209d9
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movq %r15, %rcx
jmp 0x209d4
testq %r15, %r15
je 0x209d9
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %r12, %rcx
callq 0x20c3d
incq %rbx
cmpq %rbx, 0x20(%rsp)
jne 0x20957
jmp 0x209f3
movq 0x10(%rsp), %rdi
movq %r14, %rsi
jmp 0x209d1
movq 0x28(%rsp), %rcx
incq %rcx
movq 0xa8(%rsp), %rax
addq %rax, %r13
addq %rax, %rbp
cmpq 0x70(%rsp), %rcx
jne 0x20945
movq 0xa0(%rsp), %rdi
callq 0xe5b0
jmp 0x20b5f
xorl %r12d, %r12d
testl %r12d, %r12d
jle 0x20b34
movl %r12d, %ebx
movl $0x10, %ebp
xorl %r12d, %r12d
movq %rbx, 0xa8(%rsp)
movq 0x88(%rsp), %rax
movq -0x10(%rax,%rbp), %r15
movq -0x8(%rax,%rbp), %r14
movq (%rax,%rbp), %r13
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
movq %r15, %rsi
movq %r14, %rdx
movq %r13, %rcx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
jne 0x20af2
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
movq %r15, %rsi
movq %r13, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
jne 0x20af2
addq $0x18, %r15
movq 0x10(%rsp), %rbx
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq *0x20(%rax)
movq %rax, %r15
addq $0x18, %r14
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq *0x20(%rax)
movq %rax, %r14
addq $0x18, %r13
movq (%rbx), %rax
movq %rbx, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq *0x20(%rax)
movq (%rbx), %r9
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %rax, %rcx
xorl %r8d, %r8d
callq *0x48(%r9)
movq 0xa8(%rsp), %rbx
testq %rax, %rax
je 0x20b24
movq 0x20(%rsp), %rcx
movl (%rcx,%r12,4), %ecx
movl %ecx, 0x98(%rax)
movq 0x28(%rsp), %rcx
movl (%rcx,%r12,4), %ecx
movl %ecx, 0x9c(%rax)
movq 0x70(%rsp), %rcx
movl (%rcx,%r12,4), %ecx
movl %ecx, 0xa0(%rax)
incq %r12
addq $0x18, %rbp
cmpq %r12, %rbx
jne 0x20a45
movq 0x20(%rsp), %rdi
callq 0xe5b0
movq 0x28(%rsp), %rdi
callq 0xe5b0
movq 0x70(%rsp), %rdi
callq 0xe5b0
leaq 0x88(%rsp), %rdi
callq 0x70656
movq 0x30(%rsp), %r12
movq 0x80(%rsp), %r13
leaq 0xc4b0d(%rip), %rbp     # 0xe5680
incq %r13
movslq 0x7c(%rsp), %rax
cmpq %rax, %r13
jl 0x2000d
jmp 0x20b97
movl 0xc(%rsp), %edx
movq %r12, %rdi
movq %r14, %rsi
callq 0x40226
jmp 0x20b73
movq %r12, %rdi
callq 0xe540
movl $0x1, %ebx
jmp 0x20bbe
leaq 0x81a76(%rip), %rdi     # 0xa2623
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x72a1e
movq %r14, %rdi
callq 0xe430
movl %ebx, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x20c25
jmp 0x20c25
jmp 0x20c25
jmp 0x20c25
jmp 0x20c25
jmp 0x20c25
jmp 0x20c25
jmp 0x20c25
movq %rax, %r14
testq %rbx, %rbx
je 0x20c18
negq %rbx
movq %rbp, %r15
addq $-0x88, %r15
leaq 0xc0b02(%rip), %r12     # 0xe1700
movq %r12, -0x90(%rbp,%rbx)
leaq (%r15,%rbx), %rdi
callq 0x70656
addq $-0x98, %rbx
jne 0x20bfe
movq %rbp, %rdi
movq %r13, %rsi
callq 0xe8c0
jmp 0x20c35
movq %rax, %r14
leaq 0x88(%rsp), %rdi
callq 0x70656
movq %r14, %rdi
callq 0xe7e0