// File: tomfunkhouser[P]gaps/apps/msh2pts/msh2pts.cpp
// Function: VoteValue(gaps::R3Mesh*, gaps::R3MeshVertex*, gaps::R3MeshProperty*, int)
static RNScalar 
VoteValue(R3Mesh *mesh, R3MeshVertex *vertex, R3MeshProperty *property, int extrema_type)
{
  // Get vertex value
  RNScalar value = property->VertexValue(vertex);
  if (value == RN_UNKNOWN) return 0;

  // Compute statistics of neighbors
  int count = 0;
  RNScalar sum_value = 0;
  RNScalar minimum_value = FLT_MAX;
  RNScalar maximum_value = -FLT_MAX;
  for (int i = 0; i < mesh->VertexValence(vertex); i++) {
    R3MeshEdge *edge = mesh->EdgeOnVertex(vertex, i);
    R3MeshVertex *neighbor_vertex = mesh->VertexAcrossEdge(edge, vertex);
    RNScalar neighbor_value = property->VertexValue(mesh->VertexID(neighbor_vertex));
    if (neighbor_value == RN_UNKNOWN) continue;
    if (neighbor_value < minimum_value) minimum_value = neighbor_value;
    if (neighbor_value > maximum_value) maximum_value = neighbor_value;
    sum_value += neighbor_value;
    count++;
  }

  // Just checking
  if (count == 0) return 0;

  // Return vote value
  RNScalar mean_value = sum_value / count;
  RNScalar laplacian = value - mean_value;
  if ((extrema_type == PROPERTY_MINIMA) && (value >= minimum_value)) return 0;
  if ((extrema_type == PROPERTY_MAXIMA) && (value <= maximum_value)) return 0;
  return fabs(laplacian);
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movq %rdx, 0x78(%rsp)
movl %ecx, 0x74(%rsp)
movq 0x78(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x1b9a0
movsd %xmm0, 0x68(%rsp)
movsd 0x68(%rsp), %xmm0
movsd 0x12f8c2(%rip), %xmm1   # 0x14a038
ucomisd %xmm1, %xmm0
jne 0x1a78f
jp 0x1a78f
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0x1a97b
movl $0x0, 0x64(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x12f860(%rip), %xmm0   # 0x14a008
movsd %xmm0, 0x50(%rsp)
movsd 0x12f85a(%rip), %xmm0   # 0x14a010
movsd %xmm0, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
movl %eax, 0x14(%rsp)
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x1e5e0
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
jge 0x1a8d7
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
movl 0x44(%rsp), %edx
callq 0x1ea60
movq %rax, 0x38(%rsp)
movq 0x88(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0x1ea90
movq %rax, 0x30(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x88(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x1b320
movq 0x8(%rsp), %rdi
movl %eax, %esi
callq 0x1ba10
movsd %xmm0, 0x28(%rsp)
movsd 0x28(%rsp), %xmm0
movsd 0x12f7d0(%rip), %xmm1   # 0x14a038
ucomisd %xmm1, %xmm0
jne 0x1a872
jp 0x1a872
jmp 0x1a8c7
movsd 0x28(%rsp), %xmm1
movsd 0x50(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1a890
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x28(%rsp), %xmm0
ucomisd 0x48(%rsp), %xmm0
jbe 0x1a8aa
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x28(%rsp), %xmm0
addsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x1a7c4
cmpl $0x0, 0x64(%rsp)
jne 0x1a8ef
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0x1a97b
movsd 0x58(%rsp), %xmm0
cvtsi2sdl 0x64(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x68(%rsp), %xmm0
subsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
cmpl $0xb, 0x74(%rsp)
jne 0x1a93a
movsd 0x68(%rsp), %xmm0
ucomisd 0x50(%rsp), %xmm0
jb 0x1a93a
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0x1a97b
cmpl $0xa, 0x74(%rsp)
jne 0x1a961
movsd 0x68(%rsp), %xmm1
movsd 0x48(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x1a961
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0x1a97b
movsd 0x18(%rsp), %xmm0
movaps 0x12f702(%rip), %xmm1   # 0x14a070
pand %xmm1, %xmm0
movsd %xmm0, 0x90(%rsp)
movsd 0x90(%rsp), %xmm0
addq $0x98, %rsp
retq
nopl (%rax)