// File: tomfunkhouser[P]gaps/apps/grd2pts/grd2pts.cpp
// Function: CreatePoints(gaps::R3Grid*, gaps::R3Grid*, int, double)
static RNArray<Point *> *
CreatePoints(R3Grid *grid, R3Grid *mask, int npoints, RNLength min_spacing)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();

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

  // Compute points
  for (int i = 0; i < npoints; i++) {
    // Find maximum value
    int maximum_index = -1;
    RNScalar maximum_value = 0;
    const RNScalar *mask_valuesp = mask->GridValues();
    for (int j = 0; j < mask->NEntries(); j++) {
      if (*mask_valuesp > maximum_value) { maximum_value = *mask_valuesp; maximum_index = j; }
      mask_valuesp++;
    }

    // Check if found value greater than zero
    if (maximum_index < 0) break;

    // Determine world position and normal
    int x, y, z;
    mask->IndexToIndices(maximum_index, x, y, z);
    R3Point position = grid->WorldPosition(x, y, z);
    R3Vector gradient = R3zero_vector; // grid->WorldGradientVector(x, y, z);
    gradient.Normalize();

    // Create point
    Point *point = new Point(position, gradient, maximum_value);
    assert(point);

    // Add point to list
    points->Insert(point);

    // Mask area around point 
    if (min_spacing > 0) mask->RasterizeWorldSphere(position, min_spacing, -maximum_value);
    else mask->SetGridValue(x, y, z, 0);
  }

  // Print message
  if (print_verbose) {
    printf("Created points ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Points = %d\n", points->NEntries());
    printf("  Requested Points = %d\n", npoints);
    printf("  Min Spacing = %g\n", min_spacing);
    fflush(stdout);
  }

  // Return points
  return points;
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xd8(%rsp)
movq %rsi, 0xd0(%rsp)
movl %edx, 0xcc(%rsp)
movsd %xmm0, 0xc0(%rsp)
leaq 0xb0(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0xd1830
movq 0x28(%rsp), %rdi
callq 0x13fe0
movl $0x10, %edi
callq 0xf4c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x30(%rsp)
callq 0x14610
jmp 0x13acf
movq 0x30(%rsp), %rax
movq %rax, 0xa8(%rsp)
cmpq $0x0, 0xa8(%rsp)
jne 0x13b2e
leaq 0x120842(%rip), %rdi    # 0x134330
movb $0x0, %al
callq 0xd5a50
movq $0x0, 0xe0(%rsp)
jmp 0x13e0e
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
movl $0x10, %esi
callq 0xf4d0
jmp 0x13e1e
movl $0x0, 0x98(%rsp)
movl 0x98(%rsp), %eax
cmpl 0xcc(%rsp), %eax
jge 0x13d70
movl $0xffffffff, 0x94(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movsd %xmm0, 0x88(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x14620
movq %rax, 0x80(%rsp)
movl $0x0, 0x7c(%rsp)
movl 0x7c(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x14640
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x13bf8
movq 0x80(%rsp), %rax
movsd (%rax), %xmm0
ucomisd 0x88(%rsp), %xmm0
jbe 0x13bd7
movq 0x80(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x88(%rsp)
movl 0x7c(%rsp), %eax
movl %eax, 0x94(%rsp)
movq 0x80(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x80(%rsp)
movl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7c(%rsp)
jmp 0x13b81
cmpl $0x0, 0x94(%rsp)
jge 0x13c07
jmp 0x13d70
movq 0xd0(%rsp), %rdi
movl 0x94(%rsp), %esi
leaq 0x78(%rsp), %rdx
leaq 0x74(%rsp), %rcx
leaq 0x70(%rsp), %r8
callq 0x14660
movq 0xd8(%rsp), %rsi
cvtsi2sdl 0x78(%rsp), %xmm0
cvtsi2sdl 0x74(%rsp), %xmm1
cvtsi2sdl 0x70(%rsp), %xmm2
leaq 0x58(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x31420
leaq 0x5661b6(%rip), %rsi    # 0x579e10
leaq 0x40(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x3d100
movq 0x10(%rsp), %rdi
callq 0x3d820
movl $0x38, %edi
callq 0xf4c0
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x18(%rsp)
movsd 0x88(%rsp), %xmm0
callq 0x146d0
jmp 0x13ca2
movq 0x18(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xa8(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x14730
movsd 0xc0(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x13d3c
movq 0xd0(%rsp), %rdi
movsd 0xc0(%rsp), %xmm0
movsd 0x88(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
leaq 0x58(%rsp), %rsi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x14760
jmp 0x13d58
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
movl $0x38, %esi
callq 0xf4d0
jmp 0x13e1e
movq 0xd0(%rsp), %rdi
movl 0x78(%rsp), %esi
movl 0x74(%rsp), %edx
movl 0x70(%rsp), %ecx
xorps %xmm0, %xmm0
callq 0x14570
jmp 0x13d5a
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0x13b39
cmpl $0x0, 0x1657e5(%rip)    # 0x17955c
je 0x13dfe
leaq 0x1205d0(%rip), %rdi    # 0x134354
movb $0x0, %al
callq 0xf070
leaq 0xb0(%rsp), %rdi
callq 0xd18f0
leaq 0x1202e5(%rip), %rdi    # 0x134084
movb $0x1, %al
callq 0xf070
movq 0xa8(%rsp), %rdi
callq 0x14000
movl %eax, %esi
leaq 0x1202df(%rip), %rdi    # 0x13409b
movb $0x0, %al
callq 0xf070
movl 0xcc(%rsp), %esi
leaq 0x120597(%rip), %rdi    # 0x134368
movb $0x0, %al
callq 0xf070
movsd 0xc0(%rsp), %xmm0
leaq 0x120599(%rip), %rdi    # 0x134381
movb $0x1, %al
callq 0xf070
movq 0x15c19a(%rip), %rax    # 0x16ff90
movq (%rax), %rdi
callq 0xf5d0
movq 0xa8(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
addq $0xe8, %rsp
retq
movq 0xa0(%rsp), %rdi
callq 0xf890
nopl (%rax,%rax)