// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::CreateFace(gaps::R3MeshVertex*, gaps::R3MeshVertex*, gaps::R3MeshVertex*, gaps::R3MeshEdge*, gaps::R3MeshEdge*, gaps::R3MeshEdge*, gaps::R3MeshFace*)
R3MeshFace *R3Mesh::
CreateFace(R3MeshVertex *v1, R3MeshVertex *v2, R3MeshVertex *v3,
           R3MeshEdge *e1, R3MeshEdge *e2, R3MeshEdge *e3, R3MeshFace *f)
{
  // Check if two faces share same side of same edge
  if ((e1->vertex[0] == v1) && e1->face[0]) return NULL;
  if ((e1->vertex[0] == v2) && e1->face[1]) return NULL;
  if ((e2->vertex[0] == v2) && e2->face[0]) return NULL;
  if ((e2->vertex[0] == v3) && e2->face[1]) return NULL;
  if ((e3->vertex[0] == v3) && e3->face[0]) return NULL;
  if ((e3->vertex[0] == v1) && e3->face[1]) return NULL;

  // Invalidate GL buffer objects
  InvalidateGLBufferObjects();

  // Create face
  if (!f) {
    f = new R3MeshFace();
    f->flags.Add(R3_MESH_FACE_ALLOCATED);
  }

  // Update face pointers
  UpdateFaceRefs(f, v1, v2, v3, e1, e2, e3);

  // Set face ID
  f->id = faces.NEntries();

  // Insert face into array
  faces.Insert(f);

  // Return face
  return f;
}

// Assembly:
subq $0x78, %rsp
movq 0x88(%rsp), %rax
movq 0x80(%rsp), %rax
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq %rdx, 0x58(%rsp)
movq %rcx, 0x50(%rsp)
movq %r8, 0x48(%rsp)
movq %r9, 0x40(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x60(%rsp), %rax
jne 0x1ac76
movq 0x48(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x1ac76
movq $0x0, 0x70(%rsp)
jmp 0x1ae6c
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x58(%rsp), %rax
jne 0x1aca0
movq 0x48(%rsp), %rax
cmpq $0x0, 0x20(%rax)
je 0x1aca0
movq $0x0, 0x70(%rsp)
jmp 0x1ae6c
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x58(%rsp), %rax
jne 0x1acca
movq 0x40(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x1acca
movq $0x0, 0x70(%rsp)
jmp 0x1ae6c
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x50(%rsp), %rax
jne 0x1acf4
movq 0x40(%rsp), %rax
cmpq $0x0, 0x20(%rax)
je 0x1acf4
movq $0x0, 0x70(%rsp)
jmp 0x1ae6c
movq 0x80(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x50(%rsp), %rax
jne 0x1ad24
movq 0x80(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x1ad24
movq $0x0, 0x70(%rsp)
jmp 0x1ae6c
movq 0x80(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x60(%rsp), %rax
jne 0x1ad54
movq 0x80(%rsp), %rax
cmpq $0x0, 0x20(%rax)
je 0x1ad54
movq $0x0, 0x70(%rsp)
jmp 0x1ae6c
movq 0x20(%rsp), %rdi
movq (%rdi), %rax
callq *0x290(%rax)
cmpq $0x0, 0x88(%rsp)
jne 0x1adeb
movl $0xc8, %edi
callq 0xf4c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x18(%rsp)
callq 0x36680
jmp 0x1ad89
movq 0x18(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rax
addq $0xa8, %rax
movq %rax, 0x10(%rsp)
leaq 0x28(%rsp), %rdi
movl $0x1, %esi
callq 0x13d80
movq 0x10(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x37560
jmp 0x1adeb
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
movl $0xc8, %esi
callq 0xf4d0
jmp 0x1ae76
movq 0x20(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq 0x58(%rsp), %rcx
movq 0x50(%rsp), %r8
movq 0x48(%rsp), %r9
movq 0x40(%rsp), %r11
movq 0x80(%rsp), %r10
movq (%rdi), %rax
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
callq *0x2d8(%rax)
movq 0x20(%rsp), %rdi
addq $0x28, %rdi
callq 0x13600
movq 0x20(%rsp), %rdi
movl %eax, %ecx
movq 0x88(%rsp), %rax
movl %ecx, 0xa4(%rax)
addq $0x28, %rdi
movq 0x88(%rsp), %rsi
callq 0x37490
movq 0x88(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
addq $0x78, %rsp
retq
movq 0x38(%rsp), %rdi
callq 0xf890