// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3MeshProperty.cpp
// Function: gaps::R3MeshProperty::Gaussian(gaps::R3MeshVertex*, double) const
RNScalar R3MeshProperty::
Gaussian(R3MeshVertex *vertex, RNScalar sigma) const
{
  // Check vertex value
  RNScalar vertex_value = VertexValue(vertex);
  if (vertex_value == RN_UNKNOWN) return RN_UNKNOWN;
  if (sigma == 0) return vertex_value;

  // Get convenient variables
  RNScalar radius = 3 * sigma;
  RNScalar denom = -2 * sigma * sigma;

  // Compute array of vertices within blur filter
  RNArray<R3MeshVertex *> neighbor_vertices;
  RNLength *distances = mesh->DijkstraDistances(vertex, radius, neighbor_vertices);
  delete [] distances;

  // Compute blurred value
  RNScalar total_value = 0;
  RNScalar total_weight = 0;
  for (int j = 0; j < neighbor_vertices.NEntries(); j++) {
    R3MeshVertex *neighbor_vertex = neighbor_vertices.Kth(j);
    int neighbor_id = mesh->VertexID(neighbor_vertex);
    RNScalar value = values[neighbor_id];
    if (value == RN_UNKNOWN) continue;
    RNLength distance = distances[neighbor_id];
    if (distance > radius) continue;
    RNScalar weight = exp(distance * distance / denom); 
    total_value += weight * value;
    total_weight += weight;
  }

  // Check total weight
  if (total_weight == 0) return vertex_value;

  // Return value 
  return total_value / total_weight;
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xd8(%rsp)
movq %rsi, 0xd0(%rsp)
movsd %xmm0, 0xc8(%rsp)
movq 0xd8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
movq 0xd0(%rsp), %rsi
callq 0x2b020
movsd %xmm0, 0xc0(%rsp)
movsd 0xc0(%rsp), %xmm0
movsd 0x12993c(%rip), %xmm1   # 0x196020
ucomisd %xmm1, %xmm0
jne 0x6c702
jp 0x6c702
movsd 0x12992c(%rip), %xmm0   # 0x196020
movsd %xmm0, 0xe0(%rsp)
jmp 0x6c9ae
movsd 0xc8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x6c72d
jp 0x6c72d
movsd 0xc0(%rsp), %xmm0
movsd %xmm0, 0xe0(%rsp)
jmp 0x6c9ae
movsd 0xc8(%rsp), %xmm0
movsd 0x129f62(%rip), %xmm1   # 0x1966a0
mulsd %xmm1, %xmm0
movsd %xmm0, 0xb8(%rsp)
movsd 0xc8(%rsp), %xmm1
movsd 0x129e34(%rip), %xmm2   # 0x196590
movaps %xmm1, %xmm0
mulsd %xmm2, %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0xb0(%rsp)
leaq 0xa0(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x712b0
movq 0x38(%rsp), %rax
movq 0x28(%rsp), %rdx
movq (%rax), %rdi
movq 0xd0(%rsp), %rsi
movsd 0xb8(%rsp), %xmm0
xorl %eax, %eax
movl %eax, %ecx
callq 0x9a840
movq %rax, 0x30(%rsp)
jmp 0x6c7b0
movq 0x30(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x6c7da
movq 0x20(%rsp), %rdi
callq 0x22d80
xorps %xmm0, %xmm0
movsd %xmm0, 0x80(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x78(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
movl %eax, 0x18(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x2ac70
movl %eax, 0x1c(%rsp)
jmp 0x6c812
movl 0x18(%rsp), %eax
movl 0x1c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x6c954
movl 0x74(%rsp), %esi
leaq 0xa0(%rsp), %rdi
callq 0x712c0
movq %rax, 0x10(%rsp)
jmp 0x6c83a
movq 0x38(%rsp), %rax
movq 0x10(%rsp), %rcx
movq %rcx, 0x68(%rsp)
movq (%rax), %rdi
movq 0x68(%rsp), %rsi
callq 0x2b080
movl %eax, 0xc(%rsp)
jmp 0x6c85c
movq 0x38(%rsp), %rax
movl 0xc(%rsp), %ecx
movl %ecx, 0x64(%rsp)
movq 0x410(%rax), %rax
movslq 0x64(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x58(%rsp), %xmm0
movsd 0x129792(%rip), %xmm1   # 0x196020
ucomisd %xmm1, %xmm0
jne 0x6c8c1
jp 0x6c8c1
jmp 0x6c944
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x90(%rsp)
movl %eax, 0x8c(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x712e0
jmp 0x6c9bf
movq 0x98(%rsp), %rax
movslq 0x64(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x50(%rsp), %xmm0
ucomisd 0xb8(%rsp), %xmm0
jbe 0x6c8ec
jmp 0x6c944
movsd 0x50(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
divsd 0xb0(%rsp), %xmm0
callq 0x232d0
movsd %xmm0, 0x48(%rsp)
movsd 0x48(%rsp), %xmm0
movsd 0x58(%rsp), %xmm2
movsd 0x80(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x48(%rsp), %xmm0
addsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x6c7f7
movsd 0x78(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x6c981
jp 0x6c981
movsd 0xc0(%rsp), %xmm0
movsd %xmm0, 0xe0(%rsp)
movl $0x1, 0x44(%rsp)
jmp 0x6c9a1
movsd 0x80(%rsp), %xmm0
divsd 0x78(%rsp), %xmm0
movsd %xmm0, 0xe0(%rsp)
movl $0x1, 0x44(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x712e0
movsd 0xe0(%rsp), %xmm0
addq $0xe8, %rsp
retq
movq 0x90(%rsp), %rdi
callq 0x23270
nopl (%rax)