// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::SubdivideFace(gaps::R3MeshFace*)
R3MeshFace *R3Mesh::
SubdivideFace(R3MeshFace *f)
{
  // Find vertices/edges bounding face
  R3MeshVertex *v0 = VertexOnFace(f, 0);
  R3MeshEdge *e0 = EdgeOnFace(f, v0, RN_CCW);
  R3MeshVertex *v1 = VertexAcrossEdge(e0, v0);
  R3MeshEdge *e1 = EdgeOnFace(f, v1, RN_CCW);
  R3MeshVertex *v2 = VertexAcrossEdge(e1, v1);
  R3MeshEdge *e2 = EdgeOnFace(f, v2, RN_CCW);
  int m = FaceMaterial(f);
  int s = FaceSegment(f);
  int c = FaceCategory(f);

  // Delete face
  DeleteFace(f);

  // Subdivide edges
  R3MeshVertex *ve0 = SubdivideEdge(e0);
  R3MeshVertex *ve1 = SubdivideEdge(e1);
  R3MeshVertex *ve2 = SubdivideEdge(e2);

  // Create new faces
  R3MeshFace *f1 = CreateFace(v0, ve0, ve2);  
  R3MeshFace *f2 = CreateFace(v1, ve1, ve0);  
  R3MeshFace *f3 = CreateFace(v2, ve2, ve1);  
  R3MeshFace *f4 = CreateFace(ve0, ve1, ve2);  

  // Set face materials
  SetFaceMaterial(f1, m);
  SetFaceMaterial(f2, m);
  SetFaceMaterial(f3, m);
  SetFaceMaterial(f4, m);

  // Set face segments
  SetFaceSegment(f1, s);
  SetFaceSegment(f2, s);
  SetFaceSegment(f3, s);
  SetFaceSegment(f4, s);

  // Set face categorys
  SetFaceCategory(f1, c);
  SetFaceCategory(f2, c);
  SetFaceCategory(f3, c);
  SetFaceCategory(f4, c);

  // Return interior face
  return f4;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq 0x90(%rsp), %rdi
movq %rdi, 0x8(%rsp)
movq 0x88(%rsp), %rsi
xorl %edx, %edx
callq 0x13700
movq 0x8(%rsp), %rdi
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
xorl %ecx, %ecx
callq 0x37a60
movq 0x8(%rsp), %rdi
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0x36f50
movq 0x8(%rsp), %rdi
movq %rax, 0x70(%rsp)
movq 0x88(%rsp), %rsi
movq 0x70(%rsp), %rdx
xorl %ecx, %ecx
callq 0x37a60
movq 0x8(%rsp), %rdi
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
callq 0x36f50
movq 0x8(%rsp), %rdi
movq %rax, 0x60(%rsp)
movq 0x88(%rsp), %rsi
movq 0x60(%rsp), %rdx
xorl %ecx, %ecx
callq 0x37a60
movq 0x8(%rsp), %rdi
movq %rax, 0x58(%rsp)
movq 0x88(%rsp), %rsi
callq 0x369e0
movq 0x8(%rsp), %rdi
movl %eax, 0x54(%rsp)
movq 0x88(%rsp), %rsi
callq 0x36a20
movq 0x8(%rsp), %rdi
movl %eax, 0x50(%rsp)
movq 0x88(%rsp), %rsi
callq 0x36a60
movq 0x8(%rsp), %rdi
movl %eax, 0x4c(%rsp)
movq 0x88(%rsp), %rsi
movq (%rdi), %rax
callq *0x70(%rax)
movq 0x8(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq (%rdi), %rax
callq *0xc8(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x40(%rsp)
movq 0x68(%rsp), %rsi
movq (%rdi), %rax
callq *0xc8(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x38(%rsp)
movq 0x58(%rsp), %rsi
movq (%rdi), %rax
callq *0xc8(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x30(%rsp)
movq 0x80(%rsp), %rsi
movq 0x40(%rsp), %rdx
movq 0x30(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x28(%rsp)
movq 0x70(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq 0x40(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x20(%rsp)
movq 0x60(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq 0x38(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x18(%rsp)
movq 0x40(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq 0x30(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq 0x8(%rsp), %rdi
movq %rax, 0x10(%rsp)
movq 0x28(%rsp), %rsi
movl 0x54(%rsp), %edx
callq 0x369c0
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %rsi
movl 0x54(%rsp), %edx
callq 0x369c0
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movl 0x54(%rsp), %edx
callq 0x369c0
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0x54(%rsp), %edx
callq 0x369c0
movq 0x8(%rsp), %rdi
movq 0x28(%rsp), %rsi
movl 0x50(%rsp), %edx
callq 0x36a00
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %rsi
movl 0x50(%rsp), %edx
callq 0x36a00
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movl 0x50(%rsp), %edx
callq 0x36a00
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0x50(%rsp), %edx
callq 0x36a00
movq 0x8(%rsp), %rdi
movq 0x28(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x36a40
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x36a40
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x36a40
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x36a40
movq 0x10(%rsp), %rax
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)