// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::CreatePlyRangeGridFace(gaps::R3Mesh*, gaps::R3MeshVertex*, gaps::R3MeshVertex*, gaps::R3MeshVertex*, double)
static void
CreatePlyRangeGridFace(R3Mesh *mesh, 
  R3MeshVertex *v0, R3MeshVertex *v1, R3MeshVertex *v2, 
  RNScalar max_aspect_ratio = 8)
{
  // Get vertex positions
  const R3Point& p0 = mesh->VertexPosition(v0);
  const R3Point& p1 = mesh->VertexPosition(v1);
  const R3Point& p2 = mesh->VertexPosition(v2);

  // Get edge lengths
  RNScalar a = R3Distance(p0, p1);
  if (RNIsZero(a)) return;
  RNScalar b = R3Distance(p1, p2);
  if (RNIsZero(b)) return;
  RNScalar c = R3Distance(p2, p0);
  if (RNIsZero(c)) return;

  // Compute aspect ratio
  RNScalar s = (a + b + c) / 2.0;
  RNScalar da = s - a;
  if (RNIsZero(da)) return;
  RNScalar db = s - b;
  if (RNIsZero(db)) return;
  RNScalar dc = s - c;
  if (RNIsZero(dc)) return;
  RNScalar aspect = (a * b * c) / (8.0 * da * db * dc);
  if (aspect > max_aspect_ratio) return;

  // Check edge length ratios
  if (a < b) { RNScalar swap = a; a = b; b = swap; }
  if (a < c) { RNScalar swap = a; a = c; c = swap; }
  if (b < c) { RNScalar swap = b; b = c; c = swap; }
  if (a / c > max_aspect_ratio) return;

  // Create face
  mesh->CreateFace(v0, v1, v2);
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq %rdx, 0x80(%rsp)
movq %rcx, 0x78(%rsp)
movsd %xmm0, 0x70(%rsp)
movq 0x90(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0x13660
movq %rax, 0x68(%rsp)
movq 0x90(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x13660
movq %rax, 0x60(%rsp)
movq 0x90(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x13660
movq %rax, 0x58(%rsp)
movq 0x68(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x86c40
movsd %xmm0, 0x50(%rsp)
movsd 0x50(%rsp), %xmm0
leaq 0x147e99(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x3065a
jmp 0x308a3
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x86c40
movsd %xmm0, 0x48(%rsp)
movsd 0x48(%rsp), %xmm0
leaq 0x147e64(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x3068f
jmp 0x308a3
movq 0x58(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x86c40
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm0
leaq 0x147e2f(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x306c4
jmp 0x308a3
movsd 0x50(%rsp), %xmm0
addsd 0x48(%rsp), %xmm0
addsd 0x40(%rsp), %xmm0
movsd 0x102b22(%rip), %xmm1   # 0x133200
divsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x38(%rsp), %xmm0
subsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x30(%rsp), %xmm0
leaq 0x147dd9(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x3071a
jmp 0x308a3
movsd 0x38(%rsp), %xmm0
subsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x28(%rsp), %xmm0
leaq 0x147da7(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x3074c
jmp 0x308a3
movsd 0x38(%rsp), %xmm0
subsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x20(%rsp), %xmm0
leaq 0x147d75(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x3077e
jmp 0x308a3
movsd 0x50(%rsp), %xmm0
mulsd 0x48(%rsp), %xmm0
mulsd 0x40(%rsp), %xmm0
movsd 0x102a60(%rip), %xmm1   # 0x1331f8
mulsd 0x30(%rsp), %xmm1
mulsd 0x28(%rsp), %xmm1
mulsd 0x20(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x18(%rsp), %xmm0
ucomisd 0x70(%rsp), %xmm0
jbe 0x307c7
jmp 0x308a3
movsd 0x50(%rsp), %xmm1
movsd 0x48(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x307fd
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x50(%rsp), %xmm1
movsd 0x40(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x30833
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x48(%rsp), %xmm1
movsd 0x40(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x30867
movsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rsp)
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd (%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x50(%rsp), %xmm0
divsd 0x40(%rsp), %xmm0
ucomisd 0x70(%rsp), %xmm0
jbe 0x3087d
jmp 0x308a3
movq 0x90(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
movq 0x78(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
addq $0x98, %rsp
retq
nopl (%rax,%rax)