// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::SubdivideFaces()
void R3Mesh::
SubdivideFaces(void)
{
  // Remember cardinalities
  int nfaces = NFaces();
  int nedges = NEdges();
  int nvertices = NVertices();

  // Allocate temporary memory for vertex indices
  int *vertex_indices = new int [ nfaces * 4 * 3 ];

  // Compute vertex indices for new faces
  for (int i = 0; i < nfaces; i++) {
    R3MeshFace *face = Face(i);
    R3MeshVertex *v0 = VertexOnFace(face, 0);
    R3MeshVertex *v1 = VertexOnFace(face, 1);
    R3MeshVertex *v2 = VertexOnFace(face, 2);
    R3MeshEdge *e0 = EdgeOnFace(face, 0);
    R3MeshEdge *e1 = EdgeOnFace(face, 1);
    R3MeshEdge *e2 = EdgeOnFace(face, 2);
    vertex_indices[i * 12 + 0] = VertexID(v0);
    vertex_indices[i * 12 + 1] = nvertices + EdgeID(e0);
    vertex_indices[i * 12 + 2] = nvertices + EdgeID(e2);
    vertex_indices[i * 12 + 3] = VertexID(v1);
    vertex_indices[i * 12 + 4] = nvertices + EdgeID(e1);
    vertex_indices[i * 12 + 5] = nvertices + EdgeID(e0);
    vertex_indices[i * 12 + 6] = VertexID(v2);
    vertex_indices[i * 12 + 7] = nvertices + EdgeID(e2);
    vertex_indices[i * 12 + 8] = nvertices + EdgeID(e1);
    vertex_indices[i * 12 + 9] = nvertices + EdgeID(e0);
    vertex_indices[i * 12 + 10] = nvertices + EdgeID(e1);
    vertex_indices[i * 12 + 11] = nvertices + EdgeID(e2);
  }

  // Create vertex at midpoint of every edge
  for (int i = 0; i < nedges; i++) {
    R3MeshEdge *edge = Edge(i);
    R3MeshVertex *v0 = VertexOnEdge(edge, 0);
    R3MeshVertex *v1 = VertexOnEdge(edge, 1);
    R3MeshVertex *vertex = CreateVertex(EdgeMidpoint(edge));
    SetVertexTextureCoords(vertex, 0.5*VertexTextureCoords(v0) + 0.5*VertexTextureCoords(v1)); 
    SetVertexColor(vertex, 0.5*VertexColor(v0) + 0.5*VertexColor(v1)); 
  }

  // Delete all edges and faces
  while (NFaces() > 0) DeleteFace(Face(0));
  while (NEdges() > 0) DeleteEdge(Edge(0));

  // Create new edges and faces
  for (int i = 0; i < nfaces; i++) {
    for (int j = 0; j < 4; j++) {
      R3MeshVertex *v0 = Vertex(vertex_indices[i*12 + j*3 + 0]);
      R3MeshVertex *v1 = Vertex(vertex_indices[i*12 + j*3 + 1]);
      R3MeshVertex *v2 = Vertex(vertex_indices[i*12 + j*3 + 2]);
      CreateFace(v0, v1, v2);
    }
  }

  // Delete temporary memory for vertex indices
  delete [] vertex_indices;
}

// Assembly:
subq $0x188, %rsp            # imm = 0x188
movq %rdi, 0x180(%rsp)
movq 0x180(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x135a0
movq 0x48(%rsp), %rdi
movl %eax, 0x17c(%rsp)
callq 0x135c0
movq 0x48(%rsp), %rdi
movl %eax, 0x178(%rsp)
callq 0x135e0
movl %eax, 0x174(%rsp)
movl 0x17c(%rsp), %eax
shll $0x2, %eax
imull $0x3, %eax, %eax
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0xf030
movq %rax, 0x168(%rsp)
movl $0x0, 0x164(%rsp)
movl 0x164(%rsp), %eax
cmpl 0x17c(%rsp), %eax
jge 0x1f2f7
movq 0x48(%rsp), %rdi
movl 0x164(%rsp), %esi
callq 0x136d0
movq 0x48(%rsp), %rdi
movq %rax, 0x158(%rsp)
movq 0x158(%rsp), %rsi
xorl %edx, %edx
callq 0x13700
movq 0x48(%rsp), %rdi
movq %rax, 0x150(%rsp)
movq 0x158(%rsp), %rsi
movl $0x1, %edx
callq 0x13700
movq 0x48(%rsp), %rdi
movq %rax, 0x148(%rsp)
movq 0x158(%rsp), %rsi
movl $0x2, %edx
callq 0x13700
movq 0x48(%rsp), %rdi
movq %rax, 0x140(%rsp)
movq 0x158(%rsp), %rsi
xorl %edx, %edx
callq 0x13d30
movq 0x48(%rsp), %rdi
movq %rax, 0x138(%rsp)
movq 0x158(%rsp), %rsi
movl $0x1, %edx
callq 0x13d30
movq 0x48(%rsp), %rdi
movq %rax, 0x130(%rsp)
movq 0x158(%rsp), %rsi
movl $0x2, %edx
callq 0x13d30
movq 0x48(%rsp), %rdi
movq %rax, 0x128(%rsp)
movq 0x150(%rsp), %rsi
callq 0x36910
movq 0x48(%rsp), %rdi
movl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x138(%rsp), %rsi
callq 0x36980
movl 0x24(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x28(%rsp)
movq 0x128(%rsp), %rsi
callq 0x36980
movl 0x28(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq 0x148(%rsp), %rsi
callq 0x36910
movq 0x48(%rsp), %rdi
movl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x130(%rsp), %rsi
callq 0x36980
movl 0x2c(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x4, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0x138(%rsp), %rsi
callq 0x36980
movl 0x30(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x5, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq 0x140(%rsp), %rsi
callq 0x36910
movq 0x48(%rsp), %rdi
movl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x6, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x128(%rsp), %rsi
callq 0x36980
movl 0x34(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x7, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x38(%rsp)
movq 0x130(%rsp), %rsi
callq 0x36980
movl 0x38(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x8, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x3c(%rsp)
movq 0x138(%rsp), %rsi
callq 0x36980
movl 0x3c(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0x9, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x40(%rsp)
movq 0x130(%rsp), %rsi
callq 0x36980
movl 0x40(%rsp), %edx
movq 0x48(%rsp), %rdi
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0xa, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x174(%rsp), %eax
movl %eax, 0x44(%rsp)
movq 0x128(%rsp), %rsi
callq 0x36980
movl 0x44(%rsp), %edx
addl %eax, %edx
movq 0x168(%rsp), %rax
imull $0xc, 0x164(%rsp), %ecx
addl $0xb, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl 0x164(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x164(%rsp)
jmp 0x1ef5d
movl $0x0, 0x124(%rsp)
movl 0x124(%rsp), %eax
cmpl 0x178(%rsp), %eax
jge 0x1f4dd
movq 0x48(%rsp), %rdi
movl 0x124(%rsp), %esi
callq 0x36930
movq 0x48(%rsp), %rdi
movq %rax, 0x118(%rsp)
movq 0x118(%rsp), %rsi
xorl %edx, %edx
callq 0x36960
movq 0x48(%rsp), %rdi
movq %rax, 0x110(%rsp)
movq 0x118(%rsp), %rsi
movl $0x1, %edx
callq 0x36960
movq 0x48(%rsp), %rsi
movq %rax, 0x108(%rsp)
movq 0x118(%rsp), %rdx
leaq 0xe8(%rsp), %rdi
callq 0x37990
movq 0x48(%rsp), %rdi
movq (%rdi), %rax
leaq 0xe8(%rsp), %rsi
xorl %ecx, %ecx
movl %ecx, %edx
callq *0x20(%rax)
movq 0x48(%rsp), %rdi
movq %rax, 0x100(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x110(%rsp), %rsi
callq 0x368f0
movq %rax, %rsi
leaq 0xc8(%rsp), %rdi
movsd 0x113c3b(%rip), %xmm0   # 0x133010
callq 0x37910
movq 0x48(%rsp), %rdi
movq 0x108(%rsp), %rsi
callq 0x368f0
movq %rax, %rsi
leaq 0xb8(%rsp), %rdi
movsd 0x113c11(%rip), %xmm0   # 0x133010
callq 0x37910
leaq 0xd8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0xc3750
movq 0x10(%rsp), %rsi
movq 0x48(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
callq 0x376a0
movq 0x48(%rsp), %rdi
movq 0x100(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x110(%rsp), %rsi
callq 0x368d0
movq %rax, %rsi
leaq 0x88(%rsp), %rdi
movsd 0x113ba6(%rip), %xmm0   # 0x133010
callq 0x37950
movq 0x48(%rsp), %rdi
movq 0x108(%rsp), %rsi
callq 0x368d0
movq %rax, %rsi
leaq 0x70(%rsp), %rdi
movsd 0x113b7f(%rip), %xmm0   # 0x133010
callq 0x37950
leaq 0xa0(%rsp), %rdi
leaq 0x88(%rsp), %rsi
leaq 0x70(%rsp), %rdx
callq 0x37200
movq 0x48(%rsp), %rdi
movq 0x18(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x37670
movl 0x124(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x124(%rsp)
jmp 0x1f302
jmp 0x1f4df
movq 0x48(%rsp), %rdi
callq 0x135a0
cmpl $0x0, %eax
jle 0x1f50a
movq 0x48(%rsp), %rdi
xorl %esi, %esi
callq 0x136d0
movq 0x48(%rsp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
callq *0x70(%rax)
jmp 0x1f4df
jmp 0x1f50c
movq 0x48(%rsp), %rdi
callq 0x135c0
cmpl $0x0, %eax
jle 0x1f537
movq 0x48(%rsp), %rdi
xorl %esi, %esi
callq 0x36930
movq 0x48(%rsp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
callq *0x68(%rax)
jmp 0x1f50c
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x17c(%rsp), %eax
jge 0x1f626
movl $0x0, 0x68(%rsp)
cmpl $0x4, 0x68(%rsp)
jge 0x1f614
movq 0x48(%rsp), %rdi
movq 0x168(%rsp), %rax
imull $0xc, 0x6c(%rsp), %ecx
imull $0x3, 0x68(%rsp), %edx
addl %edx, %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
callq 0x13630
movq 0x48(%rsp), %rdi
movq %rax, 0x60(%rsp)
movq 0x168(%rsp), %rax
imull $0xc, 0x6c(%rsp), %ecx
imull $0x3, 0x68(%rsp), %edx
addl %edx, %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
callq 0x13630
movq 0x48(%rsp), %rdi
movq %rax, 0x58(%rsp)
movq 0x168(%rsp), %rax
imull $0xc, 0x6c(%rsp), %ecx
imull $0x3, 0x68(%rsp), %edx
addl %edx, %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
callq 0x13630
movq 0x48(%rsp), %rdi
movq %rax, 0x50(%rsp)
movq 0x60(%rsp), %rsi
movq 0x58(%rsp), %rdx
movq 0x50(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0x1f558
jmp 0x1f616
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x1f53f
movq 0x168(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x1f643
movq 0x8(%rsp), %rdi
callq 0xf670
addq $0x188, %rsp            # imm = 0x188
retq
nopl (%rax,%rax)