// File: tomfunkhouser[P]gaps/apps/sfl2pts/sfl2pts.cpp
// Function: CreatePoints(gaps::R3SurfelScene*, gaps::RNArray<PlyPoint*>&)
static int
CreatePoints(R3SurfelScene *scene, RNArray<PlyPoint *>& points)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();

  // Get useful variables
  R3SurfelTree *tree = scene->Tree();
  if (!tree) return 0;
  R3SurfelDatabase *database = tree->Database();
  if (!database) return 0;

  // Add point for every surfel in a leaf node
  for (int i = 0; i < tree->NNodes(); i++) {
    R3SurfelNode *node = tree->Node(i);
    if (node->NParts() > 0) continue;
    
    // Get/check scan
    R3SurfelScan *scan = node->Scan(TRUE);
    if (scan && (load_every_kth_image > 1) && ((scan->SceneIndex() % load_every_kth_image) != 0)) {
      continue;
    }

    // Get scan info
    int scan_width = (scan) ? scan->ImageWidth() : 0;      
    int scan_height = (scan) ? scan->ImageHeight() : 0;
    if ((scan_width == 0) || (scan_height == 0)) scan = NULL;
    R3Point E = (scan) ? scan->Viewpoint() : R3zero_point;
    R3Vector T = (scan) ? scan->Towards() : R3zero_vector;
    RNScalar min_dot = (scan) ? ((scan->XFOV() < scan->YFOV()) ? cos(scan->XFOV()) : cos(scan->YFOV())) : 0;
    RNScalar min_dotdot = min_dot * min_dot;

    // Process blocks
    for (int i = 0; i < node->NBlocks(); i++) {
      R3SurfelBlock *block = node->Block(i);

      // Read block
      database->ReadBlock(block);

      // Process surfels
      for (int j = 0; j < block->NSurfels(); j++) {
        const R3Surfel *surfel = block->Surfel(j);

        // Check sample probability
        if (RNIsLess(sample_probability, 1.0)) {
          if (RNRandomScalar() > sample_probability) continue;
        }

        // Check if on boundary
        if (omit_boundaries) {
          if (surfel->IsOnSilhouetteBoundary()) continue;
          if (surfel->IsOnShadowBoundary()) continue;
        }
        
        // Get info
        RNScalar confidence = 1.0;
        R3Point P = block->SurfelPosition(j);
        R3Vector N = block->SurfelNormal(j);

        // Update info based on scan
        if (scan) {
          // Get scan view info
          R3Vector V = P - E;

          // Get/check depth
          RNLength d = V.Dot(T);
          if (d < RN_EPSILON) continue;
          if ((max_depth > 0) && (d > max_depth)) continue;
          V.Normalize();

          // Check if outside elipse centered in image
          if (omit_corners) {
            RNScalar dot = T.Dot(V);
            if (dot*dot < min_dotdot) continue;
          }

          // Update confidence
          // RNScalar NdotV = N.Dot(V);
          // if (NdotV >= 0) continue;
          // confidence *= -NdotV;
          // confidence *= T.Dot(V);
          if (d > 1.0) confidence /= d*d;
          if (confidence < 1E-3F) continue;

          // Update normal
          if (scale_normals_by_confidence) {
            N[0] *= confidence;
            N[1] *= confidence;
            N[2] *= confidence;
          }
        }

        // Allocate ply point
        PlyPoint *v = new PlyPoint();
        
        // Fill in ply point position
        v->x = P.X();
        v->y = P.Y();
        v->z = P.Z();

        // Fill in ply point normal
        v->nx = N.X();
        v->ny = N.Y();
        v->nz = N.Z();

        // Fill in ply point color
        v->red = surfel->R();
        v->green = surfel->G();
        v->blue = surfel->B();

        // Fill in ply point confidence and radius
        assert(confidence <= 1.0);
        v->confidence = confidence;
        v->radius = block->SurfelRadius(j);

        // Insert point
        points.Insert(v);
      }

      // Release block
      database->ReleaseBlock(block);
    }
  }

  // Print debug statistics
  if (print_verbose) {
    printf("Created points ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Points = %u\n", points.NEntries());
    printf("  Sample probability = %g\n", sample_probability);
    fflush(stdout);
  }

  // Return success
  return 1;
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movq %rdi, 0x168(%rsp)
movq %rsi, 0x160(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x143310
leaq 0x150(%rsp), %rdi
callq 0x18850
movq 0x168(%rsp), %rdi
callq 0x187d0
movq %rax, 0x148(%rsp)
cmpq $0x0, 0x148(%rsp)
jne 0x16fb1
movl $0x0, 0x174(%rsp)
jmp 0x17786
movq 0x148(%rsp), %rdi
callq 0x187e0
movq %rax, 0x140(%rsp)
cmpq $0x0, 0x140(%rsp)
jne 0x16fe1
movl $0x0, 0x174(%rsp)
jmp 0x17786
movl $0x0, 0x13c(%rsp)
movl 0x13c(%rsp), %eax
movl %eax, 0x54(%rsp)
movq 0x148(%rsp), %rdi
callq 0x18910
movl %eax, %ecx
movl 0x54(%rsp), %eax
cmpl %ecx, %eax
jge 0x17707
movq 0x148(%rsp), %rdi
movl 0x13c(%rsp), %esi
callq 0x18950
movq %rax, 0x130(%rsp)
movq 0x130(%rsp), %rdi
callq 0x18980
cmpl $0x0, %eax
jle 0x17045
jmp 0x176f1
movq 0x130(%rsp), %rdi
movl $0x1, %esi
callq 0x2a9e0
movq %rax, 0x128(%rsp)
cmpq $0x0, 0x128(%rsp)
je 0x17091
cmpl $0x1, 0x1df50f(%rip)    # 0x1f6580
jle 0x17091
movq 0x128(%rsp), %rdi
callq 0x189a0
cltd
idivl 0x1df4f9(%rip)          # 0x1f6580
cmpl $0x0, %edx
je 0x17091
jmp 0x176f1
cmpq $0x0, 0x128(%rsp)
je 0x170af
movq 0x128(%rsp), %rdi
callq 0x189b0
movl %eax, 0x50(%rsp)
jmp 0x170b7
xorl %eax, %eax
movl %eax, 0x50(%rsp)
jmp 0x170b7
movl 0x50(%rsp), %eax
movl %eax, 0x124(%rsp)
cmpq $0x0, 0x128(%rsp)
je 0x170e0
movq 0x128(%rsp), %rdi
callq 0x189d0
movl %eax, 0x4c(%rsp)
jmp 0x170e8
xorl %eax, %eax
movl %eax, 0x4c(%rsp)
jmp 0x170e8
movl 0x4c(%rsp), %eax
movl %eax, 0x120(%rsp)
cmpl $0x0, 0x124(%rsp)
je 0x17107
cmpl $0x0, 0x120(%rsp)
jne 0x17113
movq $0x0, 0x128(%rsp)
cmpq $0x0, 0x128(%rsp)
je 0x17132
movq 0x128(%rsp), %rdi
callq 0x189f0
movq %rax, 0x40(%rsp)
jmp 0x17140
leaq 0x5ea177(%rip), %rax    # 0x6012b0
movq %rax, 0x40(%rsp)
jmp 0x17140
movq 0x40(%rsp), %rsi
leaq 0x108(%rsp), %rdi
callq 0xfa170
cmpq $0x0, 0x128(%rsp)
je 0x17174
movq 0x128(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0x18a10
jmp 0x17188
leaq 0xf0(%rsp), %rdi
leaq 0x5ea21d(%rip), %rsi    # 0x6013a0
callq 0xfb2d0
cmpq $0x0, 0x128(%rsp)
je 0x171ff
movq 0x128(%rsp), %rdi
callq 0x18a60
movsd %xmm0, 0x38(%rsp)
movq 0x128(%rsp), %rdi
callq 0x18ac0
movsd 0x38(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x171d9
movq 0x128(%rsp), %rdi
callq 0x18a60
callq 0x13a30
movsd %xmm0, 0x30(%rsp)
jmp 0x171f1
movq 0x128(%rsp), %rdi
callq 0x18ac0
callq 0x13a30
movsd %xmm0, 0x30(%rsp)
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
jmp 0x1720a
xorps %xmm0, %xmm0
movsd %xmm0, 0x28(%rsp)
jmp 0x1720a
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
movsd 0xe8(%rsp), %xmm0
mulsd 0xe8(%rsp), %xmm0
movsd %xmm0, 0xe0(%rsp)
movl $0x0, 0xdc(%rsp)
movl 0xdc(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x130(%rsp), %rdi
callq 0x18b20
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x176ef
movq 0x130(%rsp), %rdi
movl 0xdc(%rsp), %esi
callq 0x18b40
movq %rax, 0xd0(%rsp)
movq 0x140(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x18b70
movl $0x0, 0xcc(%rsp)
movl 0xcc(%rsp), %eax
movl %eax, 0x20(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x18bf0
movl %eax, %ecx
movl 0x20(%rsp), %eax
cmpl %ecx, %eax
jge 0x176c4
movq 0xd0(%rsp), %rdi
movl 0xcc(%rsp), %esi
callq 0x18c00
movq %rax, 0xc0(%rsp)
movsd 0x1df29d(%rip), %xmm0   # 0x1f6588
leaq 0x1e8436(%rip), %rax    # 0x1ff728
movsd (%rax), %xmm2
movsd 0x18ed0a(%rip), %xmm1   # 0x1a6008
callq 0x18c20
cmpl $0x0, %eax
je 0x1731e
callq 0x146d10
ucomisd 0x1df273(%rip), %xmm0   # 0x1f6588
jbe 0x1731c
jmp 0x176ae
jmp 0x1731e
cmpl $0x0, 0x1e84ab(%rip)    # 0x1ff7d0
je 0x17357
movq 0xc0(%rsp), %rdi
callq 0x18c50
cmpl $0x0, %eax
je 0x1733e
jmp 0x176ae
movq 0xc0(%rsp), %rdi
callq 0x18c70
cmpl $0x0, %eax
je 0x17355
jmp 0x176ae
jmp 0x17357
movsd 0x18eca9(%rip), %xmm0   # 0x1a6008
movsd %xmm0, 0xb8(%rsp)
movq 0xd0(%rsp), %rsi
movl 0xcc(%rsp), %edx
leaq 0xa0(%rsp), %rdi
callq 0x18c90
movq 0xd0(%rsp), %rsi
movl 0xcc(%rsp), %edx
leaq 0x88(%rsp), %rdi
callq 0x18d90
cmpq $0x0, 0x128(%rsp)
je 0x17557
leaq 0x70(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0xfa490
leaq 0x70(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0xfb8a0
movsd %xmm0, 0x68(%rsp)
movsd 0x68(%rsp), %xmm1
leaq 0x1e833a(%rip), %rax    # 0x1ff728
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x173fd
jmp 0x176ae
movsd 0x1e83d3(%rip), %xmm0   # 0x1ff7d8
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x17423
movsd 0x68(%rsp), %xmm0
ucomisd 0x1e83bc(%rip), %xmm0   # 0x1ff7d8
jbe 0x17423
jmp 0x176ae
leaq 0x70(%rsp), %rdi
callq 0xfb9f0
cmpl $0x0, 0x1e8398(%rip)    # 0x1ff7cc
je 0x17470
leaq 0xf0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0xfb8a0
movsd %xmm0, 0x60(%rsp)
movsd 0x60(%rsp), %xmm1
mulsd 0x60(%rsp), %xmm1
movsd 0xe0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1746e
jmp 0x176ae
jmp 0x17470
movsd 0x68(%rsp), %xmm0
movsd 0x18eb8a(%rip), %xmm1   # 0x1a6008
ucomisd %xmm1, %xmm0
jbe 0x174a6
movsd 0x68(%rsp), %xmm1
mulsd 0x68(%rsp), %xmm1
movsd 0xb8(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0xb8(%rsp)
movsd 0x18eb62(%rip), %xmm0   # 0x1a6010
ucomisd 0xb8(%rsp), %xmm0
jbe 0x174be
jmp 0x176ae
cmpl $0x0, 0x1df0cb(%rip)    # 0x1f6590
je 0x17555
movsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x88(%rsp), %rdi
xorl %esi, %esi
callq 0x18e30
movsd 0x8(%rsp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, (%rax)
movsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x88(%rsp), %rdi
movl $0x1, %esi
callq 0x18e30
movsd 0x10(%rsp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, (%rax)
movsd 0xb8(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x88(%rsp), %rdi
movl $0x2, %esi
callq 0x18e30
movsd 0x18(%rsp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x17557
movl $0x24, %edi
callq 0x13570
movq %rax, %rdi
movq %rdi, (%rsp)
xorl %esi, %esi
movl $0x24, %edx
callq 0x132c0
movq (%rsp), %rax
movq %rax, 0x58(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x18e50
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, (%rax)
leaq 0xa0(%rsp), %rdi
callq 0x18e60
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0x4(%rax)
leaq 0xa0(%rsp), %rdi
callq 0x18e70
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0x8(%rax)
leaq 0x88(%rsp), %rdi
callq 0x18e80
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0xc(%rax)
leaq 0x88(%rsp), %rdi
callq 0x18e90
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0x10(%rax)
leaq 0x88(%rsp), %rdi
callq 0x18ea0
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0x14(%rax)
movq 0xc0(%rsp), %rdi
callq 0x18eb0
movb %al, %cl
movq 0x58(%rsp), %rax
movb %cl, 0x18(%rax)
movq 0xc0(%rsp), %rdi
callq 0x18ec0
movb %al, %cl
movq 0x58(%rsp), %rax
movb %cl, 0x19(%rax)
movq 0xc0(%rsp), %rdi
callq 0x18ed0
movb %al, %cl
movq 0x58(%rsp), %rax
movb %cl, 0x1a(%rax)
movsd 0xb8(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0x1c(%rax)
movq 0xd0(%rsp), %rdi
movl 0xcc(%rsp), %esi
callq 0x18ee0
cvtsd2ss %xmm0, %xmm0
movq 0x58(%rsp), %rax
movss %xmm0, 0x20(%rax)
movq 0x160(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x18f20
movl 0xcc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xcc(%rsp)
jmp 0x172a1
movq 0x140(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x18f50
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x1723f
jmp 0x176f1
movl 0x13c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x13c(%rsp)
jmp 0x16fec
cmpl $0x0, 0x1e80ba(%rip)    # 0x1ff7c8
je 0x1777b
leaq 0x18eb58(%rip), %rdi    # 0x1a626f
movb $0x0, %al
callq 0x13070
leaq 0x150(%rsp), %rdi
callq 0x1433d0
leaq 0x18ea95(%rip), %rdi    # 0x1a61c7
movb $0x1, %al
callq 0x13070
movq 0x160(%rsp), %rdi
callq 0x18810
movl %eax, %esi
leaq 0x18eb34(%rip), %rdi    # 0x1a6283
movb $0x0, %al
callq 0x13070
movsd 0x1dee2a(%rip), %xmm0   # 0x1f6588
leaq 0x18eb2f(%rip), %rdi    # 0x1a6294
movb $0x1, %al
callq 0x13070
movq 0x1de81d(%rip), %rax    # 0x1f5f90
movq (%rax), %rdi
callq 0x13680
movl $0x1, 0x174(%rsp)
movl 0x174(%rsp), %eax
addq $0x178, %rsp            # imm = 0x178
retq
nopw %cs:(%rax,%rax)