// File: /workspace/github_cpp_makefile_star2_O3/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 0x228e8
movq %rdi, %r14
cmpl $0x0, 0x10(%rdi)
je 0x228e8
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 0x25bef
testq %rax, %rax
je 0x228e8
movq %rax, %rbx
cmpl $0x0, 0x24c(%rax)
je 0x228d3
leaq 0x88(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x7667a
xorpd %xmm0, %xmm0
movq %r12, %rdi
callq 0x79b14
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 0x76f0c
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 0x6d3f4
leaq 0x88(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movsd 0xba96b(%rip), %xmm0    # 0xdd148
xorl %edx, %edx
callq 0x7cf58
leaq 0x50(%rsp), %rdi
callq 0x6e174
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x7a13a
leaq 0x88(%rsp), %rsi
movq %rbx, %rdi
callq 0x264ac
xorpd %xmm0, %xmm0
movsd 0x18(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x2282a
movsd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x22875
movsd 0x228(%rbx), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %rbx, %rdi
callq 0x768d8
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 0x228fd
ucomisd 0x10(%rsp), %xmm0
ja 0x228fd
leaq 0x11138c(%rip), %rax    # 0x133c08
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 0x3074a
leaq 0x50(%rsp), %rsi
movq %r14, %rdi
callq 0x21f14
movq %rax, %r14
movq %rbx, %rdi
callq 0x766d6
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x134f0
leaq 0x50(%rsp), %rdi
callq 0x31dba
jmp 0x22915
movq %rbx, %rdi
callq 0x766d6
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 0x766d6
movl $0x250, %esi            # imm = 0x250
movq %rbx, %rdi
callq 0x134f0
xorl %r14d, %r14d
leaq 0x88(%rsp), %rdi
callq 0x766d6
jmp 0x228eb
jmp 0x2294c
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x31dba
jmp 0x2294f
jmp 0x2294c
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6e174
jmp 0x2294f
jmp 0x2294c
jmp 0x2294c
jmp 0x2294c
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x766d6
movq %rbx, %rdi
callq 0x138b0