// File: tomfunkhouser[P]gaps/apps/msh2prp/msh2prp.cpp
// Function: CreateVertexSampling(gaps::R3Mesh*, int, double*)
static RNArray<R3MeshVertex *> *
CreateVertexSampling(R3Mesh *mesh, int num_vertices, RNScalar *weights)
{
  // Create array of selected vertices
  RNArray<R3MeshVertex *> *selected_vertices = new RNArray<R3MeshVertex *>();
  if (!selected_vertices) {
    RNFail("Unable to create array of sample vertices\n");
    return NULL;
  }

  // Check if mesh has more than num_vertices
  if (mesh->NVertices() <= num_vertices) {
    // Make list of all vertices
    for (int i = 0; i < mesh->NVertices(); i++) {
      selected_vertices->Insert(mesh->Vertex(i));
    }

    // Assign weights based on area
    for (int i = 0; i < selected_vertices->NEntries(); i++) {
      R3MeshVertex *vertex = selected_vertices->Kth(i);
      weights[i] = mesh->VertexArea(vertex);
    }
  }
  else {
    // Select random starting vertex
    int i = (int) (RNRandomScalar() * mesh->NVertices());
    R3MeshVertex *vertex = mesh->Vertex(i);
    selected_vertices->Insert(vertex);
    
    // Iteratively select furthest vertex
    for (int i = 0; i < num_vertices; i++) {

      // Compute distances from selected vertices to all vertices
      RNLength *distances = mesh->DijkstraDistances(*selected_vertices);
      
      // Find furthest vertex
      float furthest_distance = 0;
      R3MeshVertex *furthest_vertex = NULL;
      for (int j = 0; j < mesh->NVertices(); j++) {
        if (distances[j] > furthest_distance) {
          furthest_distance = distances[j];
          furthest_vertex = mesh->Vertex(j);
        }
      }
      
      // Check if found furthest vertex
      if (!furthest_vertex) break;
      
      // Add furthest vertex to selected set
      if (i == 0) selected_vertices->Truncate(0);
      selected_vertices->Insert(furthest_vertex);

      // Delete distances
      delete [] distances;
    }

    // Assign weights equally (hoping that FPS spread points evenly)
    if (weights) {
      for (int i = 0; i < selected_vertices->NEntries(); i++) {
        weights[i] = 1;
      }
    }
  }

  // Return array of selected vertices
  return selected_vertices;
}

// Assembly:
subq $0xc8, %rsp
movq %rdi, 0xb8(%rsp)
movl %esi, 0xb4(%rsp)
movq %rdx, 0xa8(%rsp)
movl $0x10, %edi
callq 0x11680
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x40(%rsp)
callq 0x1ff00
jmp 0x1d1da
movq 0x40(%rsp), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, 0xa0(%rsp)
jne 0x1d239
leaq 0x1573c2(%rip), %rdi    # 0x1745bb
movb $0x0, %al
callq 0xedb00
movq $0x0, 0xc0(%rsp)
jmp 0x1d53d
movq 0x40(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
movl $0x10, %esi
callq 0x11690
jmp 0x1d54d
movq 0xb8(%rsp), %rdi
callq 0x1f2e0
cmpl 0xb4(%rsp), %eax
jg 0x1d34c
movl $0x0, 0x90(%rsp)
movl 0x90(%rsp), %eax
movl %eax, 0x3c(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x1f2e0
movl %eax, %ecx
movl 0x3c(%rsp), %eax
cmpl %ecx, %eax
jge 0x1d2c1
movq 0xa0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xb8(%rsp), %rdi
movl 0x90(%rsp), %esi
callq 0x1f380
movq 0x30(%rsp), %rdi
movq %rax, %rsi
callq 0x1ff10
movl 0x90(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x90(%rsp)
jmp 0x1d25e
movl $0x0, 0x8c(%rsp)
movl 0x8c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x1f300
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x1d347
movq 0xa0(%rsp), %rdi
movl 0x8c(%rsp), %esi
callq 0x1ffb0
movq %rax, 0x80(%rsp)
movq 0xb8(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x31590
movq 0xa8(%rsp), %rax
movslq 0x8c(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x1d2cc
jmp 0x1d52d
callq 0xed2e0
movsd %xmm0, 0x20(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x1f2e0
movsd 0x20(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x7c(%rsp)
movq 0xb8(%rsp), %rdi
movl 0x7c(%rsp), %esi
callq 0x1f380
movq %rax, 0x70(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x1ff10
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0xb4(%rsp), %eax
jge 0x1d4d0
movq 0xb8(%rsp), %rdi
movq 0xa0(%rsp), %rsi
xorps %xmm0, %xmm0
xorl %eax, %eax
movl %eax, %edx
callq 0x42820
movq %rax, 0x60(%rsp)
xorps %xmm0, %xmm0
movss %xmm0, 0x5c(%rsp)
movq $0x0, 0x50(%rsp)
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x1f2e0
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x1d472
movq 0x60(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movss 0x5c(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1d463
movq 0x60(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x5c(%rsp)
movq 0xb8(%rsp), %rdi
movl 0x4c(%rsp), %esi
callq 0x1f380
movq %rax, 0x50(%rsp)
jmp 0x1d465
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x1d3f6
cmpq $0x0, 0x50(%rsp)
jne 0x1d47c
jmp 0x1d4d0
cmpl $0x0, 0x6c(%rsp)
jne 0x1d492
movq 0xa0(%rsp), %rdi
xorl %esi, %esi
callq 0xea970
movq 0xa0(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x1ff10
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x1d4be
movq 0x10(%rsp), %rdi
callq 0x118b0
jmp 0x1d4c0
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x1d3aa
cmpq $0x0, 0xa8(%rsp)
je 0x1d52b
movl $0x0, 0x48(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x1f300
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x1d529
movq 0xa8(%rsp), %rax
movslq 0x48(%rsp), %rcx
movsd 0x156b01(%rip), %xmm0   # 0x174018
movsd %xmm0, (%rax,%rcx,8)
movl 0x48(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
jmp 0x1d4e3
jmp 0x1d52b
jmp 0x1d52d
movq 0xa0(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
addq $0xc8, %rsp
retq
movq 0x98(%rsp), %rdi
callq 0x11bb0
nopw (%rax,%rax)