// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::EdgeSwapAngleImprovement(gaps::R3MeshEdge const*) const
RNAngle R3Mesh:: 
EdgeSwapAngleImprovement(const R3MeshEdge *edge) const
{
  // Get/check faces
  R3MeshFace *f0 = FaceOnEdge(edge, 0);
  R3MeshFace *f1 = FaceOnEdge(edge, 1);
  if (!f0 || !f1) return -RN_INFINITY;

  // Get/check vertices
  R3MeshVertex *v0 = VertexOnEdge(edge, 0);
  R3MeshVertex *v1 = VertexOnEdge(edge, 1);
  R3MeshVertex *vf0 = VertexAcrossFace(f0, edge);
  R3MeshVertex *vf1 = VertexAcrossFace(f1, edge);
  if (EdgeBetweenVertices(vf0, vf1)) return -RN_INFINITY;

  // Check if swap would flip face normals
  R3Vector n0 = FaceNormal(f0);
  R3Vector n1 = FaceNormal(f1);
  const R3Point& p0 = VertexPosition(v0);
  const R3Point& p1 = VertexPosition(v1);
  const R3Point& pf0 = VertexPosition(vf0);
  const R3Point& pf1 = VertexPosition(vf1);
  R3Vector vec00 = pf0 - p0;
  R3Vector vec01 = pf1 - p0;
  R3Vector vec10 = pf0 - p1;
  R3Vector vec11 = pf1 - p1;
  R3Vector nf0 = vec01 % vec00;
  R3Vector nf1 = vec10 % vec11;
  if (RNIsNegativeOrZero(nf0.Dot(n0))) return -RN_INFINITY;
  if (RNIsNegativeOrZero(nf0.Dot(n1))) return -RN_INFINITY;
  if (RNIsNegativeOrZero(nf1.Dot(n0))) return -RN_INFINITY;
  if (RNIsNegativeOrZero(nf1.Dot(n1))) return -RN_INFINITY;

  // Compute interior angles at vertices
  R3Vector vecA = p1 - p0;
  R3Vector vecB = pf1 - pf0;
  RNAngle A00 = R3InteriorAngle(vecA, vec00);
  RNAngle A01 = R3InteriorAngle(vecA, vec01);
  RNAngle A10 = R3InteriorAngle(-vecA, vec10);
  RNAngle A11 = R3InteriorAngle(-vecA, vec11);
  RNAngle B00 = R3InteriorAngle(-vecB, vec00);
  RNAngle B01 = R3InteriorAngle(vecB, vec01);
  RNAngle B10 = R3InteriorAngle(-vecB, vec10);
  RNAngle B11 = R3InteriorAngle(vecB, vec11);

  // Determine minimum interior angles
  RNAngle A = A00;
  if (A01 < A) A = A01;
  if (A10 < A) A = A10;
  if (A11 < A) A = A11;
  RNAngle B = B00;
  if (B01 < B) B = B01;
  if (B10 < B) B = B10;
  if (B11 < B) B = B11;
  if (RNIsZero(B)) return -RN_INFINITY;

  // Compute difference in minimum interior angles
  RNAngle delta = B - A;

  // Return difference in interior angles
  return delta;
}

// Assembly:
subq $0x218, %rsp            # imm = 0x218
movq %rdi, 0x208(%rsp)
movq %rsi, 0x200(%rsp)
movq 0x208(%rsp), %rdi
movq %rdi, (%rsp)
movq 0x200(%rsp), %rsi
xorl %edx, %edx
callq 0x37050
movq (%rsp), %rdi
movq %rax, 0x1f8(%rsp)
movq 0x200(%rsp), %rsi
movl $0x1, %edx
callq 0x37050
movq %rax, 0x1f0(%rsp)
cmpq $0x0, 0x1f8(%rsp)
je 0x1f6be
cmpq $0x0, 0x1f0(%rsp)
jne 0x1f6ee
leaq 0x158e2b(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
movq (%rsp), %rdi
movq 0x200(%rsp), %rsi
xorl %edx, %edx
callq 0x36960
movq (%rsp), %rdi
movq %rax, 0x1e8(%rsp)
movq 0x200(%rsp), %rsi
movl $0x1, %edx
callq 0x36960
movq (%rsp), %rdi
movq %rax, 0x1e0(%rsp)
movq 0x1f8(%rsp), %rsi
movq 0x200(%rsp), %rdx
callq 0x37070
movq (%rsp), %rdi
movq %rax, 0x1d8(%rsp)
movq 0x1f0(%rsp), %rsi
movq 0x200(%rsp), %rdx
callq 0x37070
movq (%rsp), %rdi
movq %rax, 0x1d0(%rsp)
movq 0x1d8(%rsp), %rsi
movq 0x1d0(%rsp), %rdx
callq 0x18280
cmpq $0x0, %rax
je 0x1f7b8
leaq 0x158d61(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
movq (%rsp), %rdi
movq 0x1f8(%rsp), %rsi
callq 0x13840
movq %rax, %rsi
leaq 0x1b8(%rsp), %rdi
callq 0x6fcf0
movq (%rsp), %rdi
movq 0x1f0(%rsp), %rsi
callq 0x13840
movq %rax, %rsi
leaq 0x1a0(%rsp), %rdi
callq 0x6fcf0
movq (%rsp), %rdi
movq 0x1e8(%rsp), %rsi
callq 0x13660
movq (%rsp), %rdi
movq %rax, 0x198(%rsp)
movq 0x1e0(%rsp), %rsi
callq 0x13660
movq (%rsp), %rdi
movq %rax, 0x190(%rsp)
movq 0x1d8(%rsp), %rsi
callq 0x13660
movq (%rsp), %rdi
movq %rax, 0x188(%rsp)
movq 0x1d0(%rsp), %rsi
callq 0x13660
movq %rax, 0x180(%rsp)
movq 0x188(%rsp), %rsi
movq 0x198(%rsp), %rdx
leaq 0x168(%rsp), %rdi
callq 0x6eeb0
movq 0x180(%rsp), %rsi
movq 0x198(%rsp), %rdx
leaq 0x150(%rsp), %rdi
callq 0x6eeb0
movq 0x188(%rsp), %rsi
movq 0x190(%rsp), %rdx
leaq 0x138(%rsp), %rdi
callq 0x6eeb0
movq 0x180(%rsp), %rsi
movq 0x190(%rsp), %rdx
leaq 0x120(%rsp), %rdi
callq 0x6eeb0
leaq 0x108(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0x168(%rsp), %rdx
callq 0x70af0
leaq 0xf0(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0x70af0
leaq 0x108(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x702c0
leaq 0x158bb8(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x382c0
cmpl $0x0, %eax
je 0x1f966
leaq 0x158bb3(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
leaq 0x108(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x702c0
leaq 0x158b5e(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x382c0
cmpl $0x0, %eax
je 0x1f9c0
leaq 0x158b59(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
leaq 0xf0(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x702c0
leaq 0x158b04(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x382c0
cmpl $0x0, %eax
je 0x1fa1a
leaq 0x158aff(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
leaq 0xf0(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x702c0
leaq 0x158aaa(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x382c0
cmpl $0x0, %eax
je 0x1fa74
leaq 0x158aa5(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
movq 0x190(%rsp), %rsi
movq 0x198(%rsp), %rdx
leaq 0xd8(%rsp), %rdi
callq 0x6eeb0
movq 0x180(%rsp), %rsi
movq 0x188(%rsp), %rdx
leaq 0xc0(%rsp), %rdi
callq 0x6eeb0
leaq 0xd8(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0xb8(%rsp)
leaq 0xd8(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0xb0(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x70fa0
leaq 0x90(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0xa8(%rsp)
leaq 0x70(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x70fa0
leaq 0x70(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0x88(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x70fa0
leaq 0x50(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0x68(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0x48(%rsp)
leaq 0x28(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x70fa0
leaq 0x28(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0x40(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x8c230
movsd %xmm0, 0x20(%rsp)
movsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0xb0(%rsp), %xmm1
movsd 0x18(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1fc07
movsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0xa8(%rsp), %xmm1
movsd 0x18(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1fc2b
movsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x88(%rsp), %xmm1
movsd 0x18(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1fc4f
movsd 0x88(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x48(%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1fc79
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x40(%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1fc97
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x20(%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1fcb5
movsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x10(%rsp), %xmm0
leaq 0x15881e(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x1fcfd
leaq 0x158819(%rip), %rax    # 0x1784f0
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x210(%rsp)
jmp 0x1fd1e
movsd 0x10(%rsp), %xmm0
subsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x210(%rsp)
movsd 0x210(%rsp), %xmm0
addq $0x218, %rsp            # imm = 0x218
retq
nop