// File: 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:
subq $0x408, %rsp            # imm = 0x408
movq %rdi, 0x3f8(%rsp)
movq %rsi, 0x3f0(%rsp)
movsd %xmm0, 0x3e8(%rsp)
movsd %xmm1, 0x3e0(%rsp)
movsd %xmm2, 0x3d8(%rsp)
movsd %xmm3, 0x3d0(%rsp)
movsd %xmm4, 0x3c8(%rsp)
movsd %xmm5, 0x3c0(%rsp)
movl %edx, 0x3bc(%rsp)
cmpq $0x0, 0x3f8(%rsp)
jne 0x33360
movq $0x0, 0x400(%rsp)
jmp 0x33881
movq 0x3f8(%rsp), %rdi
callq 0x18700
cmpl $0x0, %eax
jne 0x33383
movq $0x0, 0x400(%rsp)
jmp 0x33881
movq 0x3f8(%rsp), %rdi
movsd 0x3c0(%rsp), %xmm0
movl 0x3bc(%rsp), %esi
callq 0x39b40
movq %rax, 0x3b0(%rsp)
cmpq $0x0, 0x3b0(%rsp)
jne 0x333c4
movq $0x0, 0x400(%rsp)
jmp 0x33881
movq 0x3b0(%rsp), %rdi
callq 0x43fd0
cmpl $0x0, %eax
jne 0x3341c
movq 0x3b0(%rsp), %rax
movq %rax, 0x88(%rsp)
cmpq $0x0, %rax
je 0x3340b
movq 0x88(%rsp), %rdi
callq 0xe0050
movq 0x88(%rsp), %rdi
movl $0x250, %esi            # imm = 0x250
callq 0x13580
movq $0x0, 0x400(%rsp)
jmp 0x33881
movq 0x3b0(%rsp), %rsi
leaq 0x160(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0xdffb0
movq 0x80(%rsp), %rdi
xorps %xmm0, %xmm0
callq 0xe5d60
jmp 0x3344b
leaq 0x160(%rsp), %rdi
callq 0x44040
movsd %xmm0, 0x78(%rsp)
jmp 0x33460
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x148(%rsp)
movq 0x3f0(%rsp), %rdx
leaq 0x130(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x44060
jmp 0x3348e
movsd 0x148(%rsp), %xmm0
movsd 0x3e8(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x128(%rsp)
movsd 0x148(%rsp), %xmm0
movsd 0x3e0(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x120(%rsp)
movsd 0x148(%rsp), %xmm0
movsd 0x3d8(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x118(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x187b0
movsd %xmm0, 0x70(%rsp)
jmp 0x33500
movsd 0x70(%rsp), %xmm0
movsd 0x128(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x187c0
movsd %xmm0, 0x68(%rsp)
jmp 0x3352e
movsd 0x68(%rsp), %xmm0
movsd 0x128(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x187a0
movsd %xmm0, 0x58(%rsp)
jmp 0x3355c
movsd 0x58(%rsp), %xmm0
movsd 0x120(%rsp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x187b0
movsd %xmm0, 0x48(%rsp)
jmp 0x3358a
movsd 0x48(%rsp), %xmm0
movsd 0x128(%rsp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x187c0
movsd %xmm0, 0x38(%rsp)
jmp 0x335b8
movsd 0x38(%rsp), %xmm0
movsd 0x128(%rsp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x187a0
movsd %xmm0, 0x28(%rsp)
jmp 0x335e6
movsd 0x20(%rsp), %xmm4
movsd 0x30(%rsp), %xmm3
movsd 0x40(%rsp), %xmm2
movsd 0x50(%rsp), %xmm1
movsd 0x60(%rsp), %xmm0
movsd 0x28(%rsp), %xmm5
movsd 0x118(%rsp), %xmm6
addsd %xmm6, %xmm5
leaq 0xe0(%rsp), %rdi
callq 0xc9ee0
jmp 0x33626
leaq 0x160(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
movsd 0x170b2a(%rip), %xmm0   # 0x1a4168
xorl %edx, %edx
callq 0xebb80
jmp 0x33647
leaq 0xe0(%rsp), %rdi
callq 0x1b990
movq 0x3b0(%rsp), %rsi
leaq 0x160(%rsp), %rdi
callq 0xe69c0
jmp 0x3366b
movq 0x3b0(%rsp), %rdi
leaq 0x160(%rsp), %rsi
movsd 0x170ad5(%rip), %xmm0   # 0x1a4158
callq 0x3ae20
jmp 0x3368a
movsd 0x3d0(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
ja 0x336b2
movsd 0x3c8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x3378f
movq 0x3b0(%rsp), %rdi
callq 0x440f0
movsd %xmm0, 0x18(%rsp)
jmp 0x336c7
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0xd8(%rsp)
movsd 0xd8(%rsp), %xmm1
movsd 0x3d0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x33706
movsd 0xd8(%rsp), %xmm0
ucomisd 0x3c8(%rsp), %xmm0
jbe 0x3378d
movq 0x3b0(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x33732
movq 0x10(%rsp), %rdi
callq 0xe0050
movq 0x10(%rsp), %rdi
movl $0x250, %esi            # imm = 0x250
callq 0x13580
movq $0x0, 0x400(%rsp)
movl $0x1, 0xd4(%rsp)
jmp 0x33863
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x158(%rsp)
movl %eax, 0x154(%rsp)
jmp 0x33872
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x158(%rsp)
movl %eax, 0x154(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x1b990
jmp 0x33872
jmp 0x3378f
movq 0x3b0(%rsp), %rsi
leaq 0x1c8daa(%rip), %rax    # 0x1fc548
movsd (%rax), %xmm0
leaq 0x98(%rsp), %rdi
movl $0x4, %edx
xorl %ecx, %ecx
movl $0x1, %r8d
xorps %xmm2, %xmm2
movaps %xmm2, %xmm1
callq 0x518c0
jmp 0x337c4
movq 0x3f8(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x32140
movq %rax, 0x8(%rsp)
jmp 0x337e0
movq 0x8(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x3b0(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x33816
movq (%rsp), %rdi
callq 0xe0050
movq (%rsp), %rdi
movl $0x250, %esi            # imm = 0x250
callq 0x13580
movq 0x90(%rsp), %rax
movq %rax, 0x400(%rsp)
movl $0x1, 0xd4(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x43fc0
jmp 0x33863
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x158(%rsp)
movl %eax, 0x154(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x43fc0
jmp 0x33872
leaq 0x160(%rsp), %rdi
callq 0xe0050
jmp 0x33881
leaq 0x160(%rsp), %rdi
callq 0xe0050
jmp 0x33891
movq 0x400(%rsp), %rax
addq $0x408, %rsp            # imm = 0x408
retq
movq 0x158(%rsp), %rdi
callq 0x13970
nop