// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::ConnectedComponents() const
int R3Mesh::
ConnectedComponents(void) const
{
  // Check number of faces
  if (NFaces() == 0) return 0;

  // Allocate temporary memory
  char *marks = new char [ NFaces() ];
  for (int i = 0; i < NFaces(); i++) marks[i] = 0;

  // Iterate finding connected components
  int count = 0;
  int start = 0;
  for (;;) {
    // Find an unmarked face
    R3MeshFace *seed = NULL;
    for (; start < NFaces(); start++) {
      R3MeshFace *face = Face(start);
      if (marks[FaceID(face)] == 0) {
        seed = face;
        break;
      }
    }

    // Check if found a new component
    if (!seed) break;
    else count++;

    // Mark connected component 
    RNArray<R3MeshFace *> stack;
    stack.InsertTail(seed);
    while (!stack.IsEmpty()) {
      R3MeshFace *face = stack.Tail();
      stack.RemoveTail();
      marks[FaceID(face)] = 1;
      for (int i = 0; i < 3; i++) {
        R3MeshFace *neighbor = FaceOnFace(face, i);
        if ((neighbor) && (marks[FaceID(neighbor)] == 0)) {
          stack.InsertTail(neighbor);
        }
      }
    }
  }

  // Delete temporary memory
  delete [] marks;

  // Return number of connected components
  return count;
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xc8(%rsp)
movq 0xc8(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x135a0
cmpl $0x0, %eax
jne 0x169c6
movl $0x0, 0xd4(%rsp)
jmp 0x16cba
movq 0x60(%rsp), %rdi
callq 0x135a0
movslq %eax, %rdi
callq 0xf030
movq %rax, 0xc0(%rsp)
movl $0x0, 0xbc(%rsp)
movq 0x60(%rsp), %rdi
movl 0xbc(%rsp), %eax
movl %eax, 0x5c(%rsp)
callq 0x135a0
movl %eax, %ecx
movl 0x5c(%rsp), %eax
cmpl %ecx, %eax
jge 0x16a31
movq 0xc0(%rsp), %rax
movslq 0xbc(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x169eb
movl $0x0, 0xb8(%rsp)
movl $0x0, 0xb4(%rsp)
movq $0x0, 0xa8(%rsp)
movq 0x60(%rsp), %rdi
movl 0xb4(%rsp), %eax
movl %eax, 0x58(%rsp)
callq 0x135a0
movl %eax, %ecx
movl 0x58(%rsp), %eax
cmpl %ecx, %eax
jge 0x16ae7
movq 0x60(%rsp), %rdi
movl 0xb4(%rsp), %esi
callq 0x136d0
movq 0x60(%rsp), %rdi
movq %rax, 0xa0(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0xa0(%rsp), %rsi
callq 0x369a0
movl %eax, %ecx
movq 0x50(%rsp), %rax
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x16acf
movq 0xa0(%rsp), %rax
movq %rax, 0xa8(%rsp)
jmp 0x16ae7
jmp 0x16ad1
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x16a53
cmpq $0x0, 0xa8(%rsp)
jne 0x16af7
jmp 0x16c8f
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
leaq 0x90(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x36820
movq 0x48(%rsp), %rdi
movq 0xa8(%rsp), %rsi
callq 0x36e00
jmp 0x16b2e
jmp 0x16b30
leaq 0x90(%rsp), %rdi
callq 0x36e30
movl %eax, 0x44(%rsp)
jmp 0x16b43
movl 0x44(%rsp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x16b58
jmp 0x16c7d
leaq 0x90(%rsp), %rdi
callq 0x36e50
movq %rax, 0x38(%rsp)
jmp 0x16b6c
movq 0x38(%rsp), %rax
movq %rax, 0x78(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x36e60
jmp 0x16b85
movq 0x60(%rsp), %rdi
movq 0xc0(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x78(%rsp), %rsi
callq 0x369a0
movl %eax, 0x34(%rsp)
jmp 0x16ba7
movq 0x28(%rsp), %rax
movl 0x34(%rsp), %ecx
movslq %ecx, %rcx
movb $0x1, (%rax,%rcx)
movl $0x0, 0x74(%rsp)
cmpl $0x3, 0x74(%rsp)
jge 0x16c78
movq 0x60(%rsp), %rdi
movq 0x78(%rsp), %rsi
movl 0x74(%rsp), %edx
callq 0x36e80
movq %rax, 0x20(%rsp)
jmp 0x16be4
movq 0x20(%rsp), %rax
movq %rax, 0x68(%rsp)
cmpq $0x0, 0x68(%rsp)
je 0x16c66
movq 0x60(%rsp), %rdi
movq 0xc0(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x68(%rsp), %rsi
callq 0x369a0
movl %eax, 0x1c(%rsp)
jmp 0x16c18
movq 0x10(%rsp), %rax
movl 0x1c(%rsp), %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x16c66
movq 0x68(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x36e00
jmp 0x16c41
jmp 0x16c66
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x88(%rsp)
movl %eax, 0x84(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x36830
jmp 0x16cc9
jmp 0x16c68
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x16bbf
jmp 0x16b30
leaq 0x90(%rsp), %rdi
callq 0x36830
jmp 0x16a47
movq 0xc0(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x16cac
movq 0x8(%rsp), %rdi
callq 0xf670
movl 0xb8(%rsp), %eax
movl %eax, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
addq $0xd8, %rsp
retq
movq 0x88(%rsp), %rdi
callq 0xf890
nopw %cs:(%rax,%rax)