// File: tomfunkhouser[P]gaps/apps/msh2pts/msh2pts.cpp
// Function: SelectVertexPoints(gaps::R3Mesh*, int, double)
static RNArray<Point *> *
SelectVertexPoints(R3Mesh *mesh, int npoints, double min_spacing)
{
  // Check number of points
  if (npoints > mesh->NVertices()) npoints = mesh->NVertices();

  // Allocate array of points
  RNArray<Point *> *points = new RNArray<Point *>();
  if (!points) {
    RNFail("Unable to allocate array of points\n");
    return NULL;
  }

  // Set vertex values = surface area associated with vertex
  RNScalar total_value = 0;
  for (int i = 0; i < mesh->NVertices(); i++) {
    R3MeshVertex *vertex = mesh->Vertex(i);
    RNScalar value = mesh->VertexArea(vertex);
    mesh->SetVertexValue(vertex, value);
    total_value += value;
  }

  // Select vertices weighted by value
  R3mesh_mark++;
  int max_iterations = 100 * npoints;
  for (int i = 0; (npoints > 0) && (i < max_iterations); i++) {
    RNScalar cumulative_value = 0;
    RNScalar target_value = RNRandomScalar() * total_value;
    for (int j = 0; j < mesh->NVertices(); j++) {
      R3MeshVertex *vertex = mesh->Vertex(j);
      if (mesh->VertexMark(vertex) != R3mesh_mark) {
        RNScalar vertex_value = mesh->VertexValue(vertex);
        cumulative_value += vertex_value;
        if ((cumulative_value >= target_value) || (j == mesh->NVertices()-1)) {
          // Insert point
          Point *point = new Point(mesh, vertex);
          points->Insert(point);
          npoints--;

          // Mark point 
          mesh->SetVertexMark(vertex, R3mesh_mark);
          total_value -= vertex_value;

          // Mark nearby points
          if (min_spacing > 0) {
            RNLength *distances = mesh->DijkstraDistances(vertex, min_spacing);
            for (int k = 0; k < mesh->NVertices(); k++) {
              R3MeshVertex *nearby_vertex = mesh->Vertex(k);
              if (mesh->VertexMark(nearby_vertex) != R3mesh_mark) {
                if (distances[k] <= min_spacing) {
                  // Mark point within min_spacing
                  mesh->SetVertexMark(nearby_vertex, R3mesh_mark);
                  total_value -= vertex_value;
                }
              }
            }
            delete [] distances;
          }

          // Break
          break;
        }
      }
    }
  }

  // Return points
  return points;
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xd8(%rsp)
movl %esi, 0xd4(%rsp)
movsd %xmm0, 0xc8(%rsp)
movl 0xd4(%rsp), %eax
movl %eax, 0x3c(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x1b460
movl %eax, %ecx
movl 0x3c(%rsp), %eax
cmpl %ecx, %eax
jle 0x14965
movq 0xd8(%rsp), %rdi
callq 0x1b460
movl %eax, 0xd4(%rsp)
movl $0x10, %edi
callq 0xf4d0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x30(%rsp)
callq 0x1b5a0
jmp 0x14981
movq 0x30(%rsp), %rax
movq %rax, 0xc0(%rsp)
cmpq $0x0, 0xc0(%rsp)
jne 0x149e0
leaq 0x135c6f(%rip), %rdi    # 0x14a60f
movb $0x0, %al
callq 0xebe00
movq $0x0, 0xe0(%rsp)
jmp 0x14dff
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
movl $0x10, %esi
callq 0xf4e0
jmp 0x14e0f
xorps %xmm0, %xmm0
movsd %xmm0, 0xa8(%rsp)
movl $0x0, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x1b460
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x14aa6
movq 0xd8(%rsp), %rdi
movl 0xa4(%rsp), %esi
callq 0x1b5b0
movq %rax, 0x98(%rsp)
movq 0xd8(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x43580
movsd %xmm0, 0x90(%rsp)
movq 0xd8(%rsp), %rdi
movq 0x98(%rsp), %rsi
movsd 0x90(%rsp), %xmm0
callq 0x1b5e0
movsd 0x90(%rsp), %xmm0
addsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
movl 0xa4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa4(%rsp)
jmp 0x149f7
leaq 0x173aa3(%rip), %rax    # 0x188550
movl (%rax), %ecx
addl $0x1, %ecx
leaq 0x173a97(%rip), %rax    # 0x188550
movl %ecx, (%rax)
imull $0x64, 0xd4(%rsp), %eax
movl %eax, 0x8c(%rsp)
movl $0x0, 0x88(%rsp)
xorl %eax, %eax
cmpl $0x0, 0xd4(%rsp)
movb %al, 0x2b(%rsp)
jle 0x14afa
movl 0x88(%rsp), %eax
cmpl 0x8c(%rsp), %eax
setl %al
movb %al, 0x2b(%rsp)
movb 0x2b(%rsp), %al
testb $0x1, %al
jne 0x14b07
jmp 0x14def
xorps %xmm0, %xmm0
movsd %xmm0, 0x80(%rsp)
callq 0xeb5e0
mulsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x1b460
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x14dd7
movq 0xd8(%rsp), %rdi
movl 0x74(%rsp), %esi
callq 0x1b5b0
movq %rax, 0x68(%rsp)
movq 0xd8(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x1b610
leaq 0x1739cf(%rip), %rcx    # 0x188550
cmpl (%rcx), %eax
je 0x14dc5
movq 0xd8(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x1b630
movsd %xmm0, 0x60(%rsp)
movsd 0x60(%rsp), %xmm0
addsd 0x80(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x80(%rsp), %xmm0
ucomisd 0x78(%rsp), %xmm0
jae 0x14bf0
movl 0x74(%rsp), %eax
movl %eax, 0x20(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x1b460
movl %eax, %ecx
movl 0x20(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x14dc3
movl $0x48, %edi
callq 0xf4d0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x18(%rsp)
movq 0xd8(%rsp), %rsi
movq 0x68(%rsp), %rdx
callq 0x1b650
jmp 0x14c19
movq 0x18(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0xc0(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x1b540
movl 0xd4(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xd4(%rsp)
movq 0xd8(%rsp), %rdi
movq 0x68(%rsp), %rsi
leaq 0x1738f6(%rip), %rax    # 0x188550
movl (%rax), %edx
callq 0x1b6e0
movsd 0x60(%rsp), %xmm1
movsd 0xa8(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0xa8(%rsp)
movsd 0xc8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x14dc1
movq 0xd8(%rsp), %rdi
movq 0x68(%rsp), %rsi
movsd 0xc8(%rsp), %xmm0
xorl %eax, %eax
movl %eax, %edx
callq 0x54770
movq %rax, 0x50(%rsp)
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0x14(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x1b460
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
jge 0x14da5
movq 0xd8(%rsp), %rdi
movl 0x4c(%rsp), %esi
callq 0x1b5b0
movq %rax, 0x40(%rsp)
movq 0xd8(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x1b610
leaq 0x17383f(%rip), %rcx    # 0x188550
cmpl (%rcx), %eax
je 0x14d93
movq 0x50(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movsd 0xc8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x14d91
movq 0xd8(%rsp), %rdi
movq 0x40(%rsp), %rsi
leaq 0x173809(%rip), %rax    # 0x188550
movl (%rax), %edx
callq 0x1b6e0
movsd 0x60(%rsp), %xmm1
movsd 0xa8(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0xa8(%rsp)
jmp 0x14d91
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
movl $0x48, %esi
callq 0xf4e0
jmp 0x14e0f
jmp 0x14d93
jmp 0x14d95
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x14cbf
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x14dbf
movq 0x8(%rsp), %rdi
callq 0xf680
jmp 0x14dc1
jmp 0x14dd7
jmp 0x14dc5
jmp 0x14dc7
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x14b2f
jmp 0x14dd9
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x14ad5
movq 0xc0(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
addq $0xe8, %rsp
retq
movq 0xb8(%rsp), %rdi
callq 0xf8a0
nopl (%rax)