// File: /workspace/github_cpp_makefile_star2_O1/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, 0x10(%rsp)
movsd %xmm3, 0x18(%rsp)
testq %rdi, %rdi
je 0x22b13
movq %rdi, %r14
cmpl $0x0, 0x10(%rdi)
je 0x22b13
movq %rsi, %r15
movsd %xmm1, 0x28(%rsp)
movsd %xmm0, 0x30(%rsp)
movsd %xmm2, 0x8(%rsp)
movq %r14, %rdi
movapd %xmm5, %xmm0
movl %edx, %esi
callq 0x25edc
testq %rax, %rax
je 0x22b13
movq %rax, %rbx
cmpl $0x0, 0x24c(%rax)
je 0x22afe
leaq 0x88(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x77420
xorpd %xmm0, %xmm0
movq %r12, %rdi
callq 0x7a79e
leaq 0x88(%rsp), %rsi
movsd 0x220(%rsi), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd (%r15), %xmm0
movsd 0x8(%r15), %xmm1
movsd 0x10(%r15), %xmm2
leaq 0x38(%rsp), %rdi
callq 0x77cba
movsd 0x30(%rsp), %xmm4
movsd 0x20(%rsp), %xmm0
mulsd %xmm0, %xmm4
movsd 0x28(%rsp), %xmm2
mulsd %xmm0, %xmm2
movsd 0x8(%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 0x6e028
leaq 0x88(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movsd 0xbb748(%rip), %xmm0    # 0xde150
xorl %edx, %edx
callq 0x7dc10
leaq 0x50(%rsp), %rdi
callq 0x6ede0
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x7adb6
leaq 0x88(%rsp), %rsi
movq %rbx, %rdi
callq 0x267d9
xorpd %xmm0, %xmm0
movsd 0x18(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x22a55
movsd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x22aa0
movsd 0x228(%rbx), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %rbx, %rdi
callq 0x77686
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x8(%rsp), %xmm1
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
movsd 0x18(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x22b28
ucomisd 0x10(%rsp), %xmm0
ja 0x22b28
leaq 0x112161(%rip), %rax    # 0x134c08
movsd (%rax), %xmm0
leaq 0x50(%rsp), %rdi
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
movq %rbx, %rsi
movl $0x4, %edx
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0x30b3e
leaq 0x50(%rsp), %rsi
movq %r14, %rdi
callq 0x22118
movq %rax, %r14
movq %rbx, %rdi
callq 0x7747c
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x134f0
leaq 0x50(%rsp), %rdi
callq 0x321ae
jmp 0x22b40
movq %rbx, %rdi
callq 0x7747c
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x134f0
xorl %r14d, %r14d
movq %r14, %rax
addq $0x2d8, %rsp            # imm = 0x2D8
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %rbx, %rdi
callq 0x7747c
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x134f0
xorl %r14d, %r14d
leaq 0x88(%rsp), %rdi
callq 0x7747c
jmp 0x22b16
jmp 0x22b77
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x321ae
jmp 0x22b7a
jmp 0x22b77
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6ede0
jmp 0x22b7a
jmp 0x22b77
jmp 0x22b77
jmp 0x22b77
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x7747c
movq %rbx, %rdi
callq 0x138b0