// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelUtils.cpp
// Function: gaps::CreateConnectedPointSet(gaps::R3SurfelPointSet*, gaps::R3Point const&, double, double, double, double, double, double, int)
R3SurfelPointSet *
CreateConnectedPointSet(R3SurfelPointSet *pointset, 
  const R3Point& seed_origin, RNScalar seed_radius, 
  RNScalar seed_min_height, RNScalar seed_max_height,
  RNScalar min_volume, RNScalar max_volume,
  RNLength grid_spacing, int max_grid_resolution)
{
  // Just checking
  if (!pointset) return NULL;
  if (pointset->NPoints() == 0) return NULL;

  // Create pointset grid
  R3Grid *pointset_grid = CreateGrid(pointset, grid_spacing, max_grid_resolution);
  if (!pointset_grid) return NULL;
  if (pointset_grid->NEntries() == 0) { delete pointset_grid; return NULL; }

  // Create seedset grid
  R3Grid seed_grid(*pointset_grid); seed_grid.Clear(0);
  RNScalar scale = seed_grid.WorldToGridScaleFactor();
  R3Point seed_grid_origin = seed_grid.GridPosition(seed_origin);
  RNScalar seed_grid_radius = scale * seed_radius;
  RNScalar seed_grid_min_height = scale * seed_min_height;
  RNScalar seed_grid_max_height = scale * seed_max_height;
  seed_grid.RasterizeGridBox(
    R3Box(seed_grid_origin.X()-seed_grid_radius, 
      seed_grid_origin.Y()-seed_grid_radius, 
      seed_grid_origin.Z()+seed_grid_min_height, 
      seed_grid_origin.X()+seed_grid_radius,  
      seed_grid_origin.Y()+seed_grid_radius, 
      seed_grid_origin.Z()+seed_grid_max_height), 
      1.0);

  // Mask seed grid to pointset grid
  seed_grid.Mask(*pointset_grid);

  // Mask to part of grid connected to seeds
  MaskToSeededConnectedComponent(*pointset_grid, seed_grid, 0.5);

  // Check volume
  if ((min_volume > 0) || (max_volume > 0)) {
    RNScalar volume = pointset_grid->Volume();
    if ((volume < min_volume) || (volume > max_volume)) {
      delete pointset_grid;
      return NULL;
    }
  }

  // Create connnected point set
  R3SurfelGridConstraint constraint(pointset_grid);
  R3SurfelPointSet *connected_pointset = CreatePointSet(pointset, &constraint);

  // Delete grid
  delete pointset_grid;

  // Return connected point set
  return connected_pointset;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x2d8, %rsp            # imm = 0x2D8
movsd %xmm4, 0x8(%rsp)
movsd %xmm3, 0x10(%rsp)
testq %rdi, %rdi
je 0x21561
movq %rdi, %r14
cmpl $0x0, 0x10(%rdi)
je 0x21561
movq %rsi, %r15
movsd %xmm1, 0x20(%rsp)
movsd %xmm0, 0x28(%rsp)
movsd %xmm2, 0x30(%rsp)
movq %r14, %rdi
movapd %xmm5, %xmm0
movl %edx, %esi
callq 0x242e5
testq %rax, %rax
je 0x21561
movq %rax, %rbx
cmpl $0x0, 0x24c(%rax)
je 0x2154c
leaq 0x88(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x6c1d2
xorpd %xmm0, %xmm0
movq %r12, %rdi
callq 0x6eeec
leaq 0x88(%rsp), %rsi
movsd 0x220(%rsi), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x38(%rsp), %rdi
movq %r15, %rdx
callq 0x2860e
movsd 0x28(%rsp), %xmm4
movsd 0x18(%rsp), %xmm0
mulsd %xmm0, %xmm4
movsd 0x20(%rsp), %xmm2
mulsd %xmm0, %xmm2
movsd 0x30(%rsp), %xmm5
mulsd %xmm0, %xmm5
movsd 0x38(%rsp), %xmm0
movsd 0x40(%rsp), %xmm7
movapd %xmm7, %xmm1
subsd %xmm4, %xmm1
movsd 0x48(%rsp), %xmm6
addsd %xmm6, %xmm2
movapd %xmm4, %xmm3
addsd %xmm0, %xmm3
subsd %xmm4, %xmm0
addsd %xmm7, %xmm4
addsd %xmm6, %xmm5
leaq 0x50(%rsp), %rdi
callq 0x63d86
leaq 0x88(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movsd 0xa6cc7(%rip), %xmm0    # 0xc8148
xorl %edx, %edx
callq 0x71c7c
leaq 0x50(%rsp), %rdi
callq 0x649ae
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x6f406
leaq 0x88(%rsp), %rsi
movq %rbx, %rdi
callq 0x24a90
xorpd %xmm0, %xmm0
movsd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x214ce
movsd 0x8(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x214f2
movq %rbx, %rdi
callq 0x2862a
movsd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x21576
ucomisd 0x8(%rsp), %xmm0
ja 0x21576
leaq 0x10372f(%rip), %rax    # 0x124c28
movsd (%rax), %xmm0
leaq 0x50(%rsp), %rdi
pushq $0x4
popq %rdx
pushq $0x1
popq %r8
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x2d9f6
leaq 0x50(%rsp), %rsi
movq %r14, %rdi
callq 0x20c50
movq %rax, %r14
movq %rbx, %rdi
callq 0x6c22a
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x13500
leaq 0x50(%rsp), %rdi
callq 0x2ec74
jmp 0x2158e
movq %rbx, %rdi
callq 0x6c22a
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x13500
xorl %r14d, %r14d
movq %r14, %rax
addq $0x2d8, %rsp            # imm = 0x2D8
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %rbx, %rdi
callq 0x6c22a
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x13500
xorl %r14d, %r14d
leaq 0x88(%rsp), %rdi
callq 0x6c22a
jmp 0x21564
jmp 0x215c5
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x2ec74
jmp 0x215c8
jmp 0x215c5
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x649ae
jmp 0x215c8
jmp 0x215c5
jmp 0x215c5
jmp 0x215c5
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x6c22a
movq %rbx, %rdi
callq 0x138f0