// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::FillHole(gaps::R3MeshEdge*, double, double)
void R3Mesh::
FillHole(R3MeshEdge *seed_edge, RNLength max_perimeter, RNLength max_planar_deviation)
{
  // Check if seed edge is on boundary
  R3MeshFace *seed_face = FaceOnEdge(seed_edge);
  if (!seed_face) return; 
  if (FaceAcrossEdge(seed_edge, seed_face)) return;
  R3MeshVertex *seed_vertex = VertexOnEdge(seed_edge, seed_face, RN_CCW);

  // Create counterclockwise linked list of boundary vertices
  R3mesh_mark++;
  R3MeshBoundaryVertexData *head = NULL;
  R3MeshBoundaryVertexData *tail = NULL;
  R3MeshEdge *edge = seed_edge;
  R3MeshVertex *vertex = seed_vertex;
  // R3MeshFace *face = seed_face;
  do {
    // Create boundary vertex 
    R3MeshBoundaryVertexData *vdata = new R3MeshBoundaryVertexData();
    vdata->vertex = vertex;
    vdata->edge = edge;
    vdata->prev = NULL;
    vdata->next = NULL;
    vdata->heappointer = NULL;
    vdata->error = 0;

    // Mark vertex (so can detect figure 8)
    SetVertexMark(vertex, R3mesh_mark);

    // Add boundary vertex to list
    if (!head) head = vdata;
    if (tail) tail->next = vdata;
    vdata->prev = tail;
    tail = vdata;

    // Update vdata error 
    if (vdata->prev) {
      R3MeshVertex *prev_vertex = vdata->prev->vertex;
      R3MeshVertex *next_vertex = VertexAcrossEdge(vdata->edge, vdata->vertex);
      const R3Point& position = VertexPosition(vertex);
      const R3Point& prev_position = VertexPosition(prev_vertex);
      const R3Point& next_position = VertexPosition(next_vertex);
      const R3Vector& prev_normal = VertexNormal(prev_vertex);
      const R3Vector& next_normal = VertexNormal(next_vertex);
      R3Vector prev_vector = prev_position - position;
      R3Vector next_vector = next_position - position;
      R3Vector cross = prev_vector % next_vector;
      RNAngle interior_angle = R3InteriorAngle(prev_vector, next_vector);
      if (cross.Dot(VertexNormal(vdata->vertex)) > 0) interior_angle = RN_TWO_PI - interior_angle;
      RNAngle normal_angle = R3InteriorAngle(prev_normal, next_normal);
      vdata->error = interior_angle + normal_angle;
    }

    // Find next vertex
    vertex = VertexAcrossEdge(edge, vertex);

    // Check for repeated vertex (figure 8)
    if (VertexMark(vertex) == R3mesh_mark) {
      if (vertex != seed_vertex) {
        // Find previous instance of repeated vertex
        R3MeshBoundaryVertexData *vdata = tail->prev;
        while (vdata->vertex != vertex) vdata = vdata->prev;

        // Remove part of list before repeated vertex
        head = vdata;
        vdata = head->prev;
        head->prev = NULL;
        while (vdata) { 
          R3MeshBoundaryVertexData *prev = vdata->prev; 
          delete vdata; 
          vdata = prev; 
        }

        // Now have a complete loop
        break;
      }
    }

    // Find next edge
    R3MeshEdge *e = edge;
    while (e) {
      R3MeshFace *f = FaceOnVertex(vertex, e, RN_CCW);
      if (!f) { assert(e != edge); edge = e; break; }
      e = EdgeOnFace(f, vertex, RN_CW);
      if (!e || (e == edge)) return; 
    } 

    // Find next face
    // face = FaceOnVertex(vertex, edge, RN_CW);
  } while (vertex != seed_vertex);

  // Complete loop
  if (head && tail) {
    // Add link between head and tail
    head->prev = tail;
    tail->next = head;

    // Update head error 
    if (head) {
      R3MeshBoundaryVertexData *vdata = head;
      R3MeshVertex *prev_vertex = vdata->prev->vertex;
      R3MeshVertex *next_vertex = vdata->next->vertex;
      const R3Point& position = VertexPosition(vertex);
      const R3Point& prev_position = VertexPosition(prev_vertex);
      const R3Point& next_position = VertexPosition(next_vertex);
      const R3Vector& prev_normal = VertexNormal(prev_vertex);
      const R3Vector& next_normal = VertexNormal(next_vertex);
      R3Vector prev_vector = prev_position - position;
      R3Vector next_vector = next_position - position;
      R3Vector cross = prev_vector % next_vector;
      RNAngle interior_angle = R3InteriorAngle(prev_vector, next_vector);
      if (cross.Dot(VertexNormal(vdata->vertex)) > 0) interior_angle = RN_TWO_PI - interior_angle;
      RNAngle normal_angle = R3InteriorAngle(prev_normal, next_normal);
      vdata->error = interior_angle + normal_angle;
    }
  }

  // Split any edges spanning (back side of) boundary
  R3MeshBoundaryVertexData *vdata = head;
  do {
    R3MeshVertex *vertex = vdata->vertex;
    for (int i = 0; i < VertexValence(vertex); i++) {
      R3MeshEdge *edge = EdgeOnVertex(vertex, i);
      if (edge == vdata->edge) continue;
      if (edge == vdata->prev->edge) continue;
      R3MeshVertex *neighbor = VertexAcrossEdge(edge, vertex);
      if (VertexMark(neighbor)) SubdivideEdge(edge);
    }
    vdata = vdata->next;
  } while (vdata != head);

  // Mark hole boundary
  UnmarkHoleBoundary(this, head);

  // Check hole boundary
  if (!CheckHoleBoundary(this, head, max_perimeter, max_planar_deviation)) return;

  // Fill hole boundary
  FillHoleBoundary(this, head);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movsd %xmm1, 0x60(%rsp)
movsd %xmm0, 0x40(%rsp)
movq %rsi, %r15
movq %rdi, (%rsp)
movq 0x18(%rsi), %rax
movq 0x20(%rsi), %rdx
movq %rdx, %rcx
testq %rdx, %rdx
jne 0x17c16
movq %rax, %rcx
testq %rax, %rax
je 0x17c22
cmpq %rcx, %rax
cmovneq %rax, %rdx
testq %rdx, %rdx
je 0x17c34
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edx, %edx
cmpq %rcx, %rax
sete %dl
movq 0x8(%r15,%rdx,8), %rdx
movl 0xcd869(%rip), %ebx     # 0xe54b0
incl %ebx
movl %ebx, 0xcd861(%rip)     # 0xe54b0
leaq 0x92392(%rip), %rax     # 0xa9fe8
movsd (%rax), %xmm0
movsd %xmm0, 0x48(%rsp)
xorl %ebp, %ebp
movq %rdx, %r14
xorl %r13d, %r13d
movq %rdx, 0x30(%rsp)
movl $0x30, %edi
callq 0xe440
xorpd %xmm0, %xmm0
movq %rax, %r12
movq %r14, (%rax)
movq %r15, 0x8(%rax)
addq $0x10, %rax
movupd %xmm0, 0x10(%r12)
movupd %xmm0, 0x20(%r12)
movl %ebx, 0x88(%r14)
testq %r13, %r13
cmoveq %r12, %r13
testq %rbp, %rbp
movq %rax, 0xc0(%rsp)
je 0x17de8
movq %r13, 0x8(%rsp)
movq %r12, 0x18(%rbp)
movq %rbp, 0x10(%r12)
movq 0x8(%r15), %r13
cmpq %r14, %r13
jne 0x17cd1
movq 0x10(%r15), %r13
movq (%rbp), %rbp
testb $0x2, 0x78(%rbp)
jne 0x17ceb
movq (%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rsi
callq *0x2b0(%rax)
testb $0x2, 0x78(%r13)
jne 0x17d02
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r13, %rsi
callq *0x2b0(%rax)
leaq 0x18(%r14), %rbx
movq %rbp, 0x50(%rsp)
leaq 0x18(%rbp), %rsi
leaq 0x18(%r13), %rbp
leaq 0x70(%rsp), %rdi
movq %rbx, %rdx
callq 0x3c78e
leaq 0x10(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x3c78e
leaq 0xc8(%rsp), %rdi
leaq 0x70(%rsp), %rbx
movq %rbx, %rsi
leaq 0x10(%rsp), %rdx
callq 0x3d8fa
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x4bc63
movapd %xmm0, 0xb0(%rsp)
movq (%r12), %rbx
testb $0x2, 0x78(%rbx)
jne 0x17d7a
movq (%rsp), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
callq *0x2b0(%rax)
movq 0x50(%rsp), %rbp
addq $0x30, %rbp
addq $0x30, %r13
addq $0x30, %rbx
leaq 0xc8(%rsp), %rdi
movq %rbx, %rsi
callq 0x3d252
movsd 0x48(%rsp), %xmm1
movapd 0xb0(%rsp), %xmm2
subsd %xmm2, %xmm1
xorpd %xmm3, %xmm3
cmpltsd %xmm0, %xmm3
andpd %xmm3, %xmm1
andnpd %xmm2, %xmm3
orpd %xmm1, %xmm3
movapd %xmm3, 0x50(%rsp)
movq %rbp, %rdi
movq %r13, %rsi
callq 0x4bc63
addsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x28(%r12)
movq 0x8(%rsp), %r13
jmp 0x17def
movq $0x0, (%rax)
movq 0x8(%r15), %rax
cmpq %r14, %rax
movq %rax, %r14
movq 0x30(%rsp), %rdx
jne 0x17e04
movq 0x10(%r15), %r14
movl 0xcd6a6(%rip), %ebx     # 0xe54b0
movq %r15, %rax
cmpq %rdx, %r14
je 0x17e1e
movq %r15, %rax
cmpl %ebx, 0x88(%r14)
je 0x17e81
xorl %ecx, %ecx
cmpq %r14, 0x8(%rax)
setne %cl
movq 0x18(%rax,%rcx,8), %rcx
testq %rcx, %rcx
je 0x17e70
cmpq %r14, 0x8(%rcx)
je 0x17e4d
cmpq %r14, 0x10(%rcx)
je 0x17e54
movl $0x28, %eax
cmpq %r14, 0x18(%rcx)
je 0x17e59
jmp 0x17c22
movl $0x30, %eax
jmp 0x17e59
movl $0x20, %eax
movq (%rcx,%rax), %rax
testq %rax, %rax
je 0x17c22
cmpq %r15, %rax
jne 0x17e1e
jmp 0x17c22
movq %rax, %r15
movq %r12, %rbp
cmpq %rdx, %r14
jne 0x17c6d
jmp 0x17ebb
movq 0xc0(%rsp), %rax
movq (%rax), %r13
leaq 0x10(%r13), %rax
cmpq %r14, (%r13)
jne 0x17e89
movq (%rax), %rdi
movq $0x0, (%rax)
testq %rdi, %rdi
je 0x17ebb
movq 0x10(%rdi), %rbx
movl $0x30, %esi
callq 0xe450
movq %rbx, %rdi
testq %rbx, %rbx
jne 0x17ea5
movq %r12, 0x10(%r13)
movq %r13, 0x18(%r12)
movq (%r12), %r15
movq %r13, 0x8(%rsp)
movq 0x18(%r13), %rax
movq (%rax), %r12
testb $0x2, 0x78(%r15)
jne 0x17eeb
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r15, %rsi
callq *0x2b0(%rax)
addq $0x18, %r14
leaq 0x18(%r15), %rbx
leaq 0x18(%r12), %r13
testb $0x2, 0x78(%r12)
jne 0x17f10
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r12, %rsi
callq *0x2b0(%rax)
addq $0x30, %r15
addq $0x30, %r12
leaq 0x70(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3c78e
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x3c78e
leaq 0xc8(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x3d8fa
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x4bc63
movapd %xmm0, 0x30(%rsp)
movq 0x8(%rsp), %r13
movq (%r13), %rbx
testb $0x2, 0x78(%rbx)
jne 0x17f81
movq (%rsp), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
callq *0x2b0(%rax)
addq $0x30, %rbx
leaq 0xc8(%rsp), %rdi
movq %rbx, %rsi
callq 0x3d252
movsd 0x48(%rsp), %xmm1
movapd 0x30(%rsp), %xmm2
subsd %xmm2, %xmm1
xorpd %xmm3, %xmm3
cmpltsd %xmm0, %xmm3
andpd %xmm3, %xmm1
andnpd %xmm2, %xmm3
orpd %xmm1, %xmm3
movapd %xmm3, 0x30(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x4bc63
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x28(%r13)
movq %r13, %rbx
movq (%rbx), %r14
movl 0x14(%r14), %eax
testl %eax, %eax
jle 0x18032
xorl %r15d, %r15d
movq 0x8(%r14), %rcx
movq (%rcx,%r15,8), %rsi
cmpq 0x8(%rbx), %rsi
je 0x18027
movq 0x10(%rbx), %rcx
cmpq 0x8(%rcx), %rsi
je 0x18027
movq 0x8(%rsi), %rcx
cmpq %r14, %rcx
jne 0x1800d
movq 0x10(%rsi), %rcx
cmpl $0x0, 0x88(%rcx)
je 0x18027
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0xc8(%rax)
movl 0x14(%r14), %eax
incq %r15
movslq %eax, %rcx
cmpq %rcx, %r15
jl 0x17fe8
movq 0x18(%rbx), %rbx
cmpq %r13, %rbx
jne 0x17fda
movq %r13, %rax
movq 0x8(%rax), %rcx
testq %rcx, %rcx
je 0x1804e
movl $0x0, 0x48(%rcx)
movq 0x18(%rax), %rax
cmpq %r13, %rax
jne 0x1803e
xorpd %xmm1, %xmm1
movsd 0x40(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x180b3
xorpd %xmm0, %xmm0
movq %r13, %r14
movq 0x8(%r14), %rbx
testq %rbx, %rbx
je 0x1809e
testb $0x2, 0x38(%rbx)
jne 0x18099
movq (%rsp), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
movsd %xmm0, 0x30(%rsp)
callq *0x2b8(%rax)
movsd 0x30(%rsp), %xmm0
addsd 0x28(%rbx), %xmm0
ucomisd 0x40(%rsp), %xmm0
ja 0x17c22
movq 0x18(%r14), %r14
cmpq %r13, %r14
jne 0x1806e
movsd 0x60(%rsp), %xmm0
ucomisd 0x8a127(%rip), %xmm0    # 0xa21e8
jbe 0x181a8
xorpd %xmm0, %xmm0
leaq 0x10(%rsp), %r14
movapd %xmm0, (%r14)
movq $0x0, 0x10(%r14)
movq %r13, %rbx
movq (%rbx), %rsi
testq %rsi, %rsi
je 0x180f4
addq $0x18, %rsi
movq %r14, %rdi
callq 0x2475e
movq 0x18(%rbx), %rbx
cmpq %r13, %rbx
jne 0x180e0
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
subq %rax, %rcx
shrq $0x3, %rcx
imull $0xaaaaaaab, %ecx, %edx # imm = 0xAAAAAAAB
movb $0x1, %bl
cmpl $0x4, %edx
jl 0x1818b
leaq 0x70(%rsp), %rdi
movq %rax, %rsi
xorl %ecx, %ecx
callq 0x3b426
movq 0x10(%rsp), %rax
cmpq %rax, 0x18(%rsp)
je 0x1818b
movl $0x1, %ebp
xorl %ecx, %ecx
leaq 0x70(%rsp), %r14
movabsq $-0x5555555555555555, %r15 # imm = 0xAAAAAAAAAAAAAAAB
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rdi
movq %r14, %rsi
callq 0x495be
ucomisd 0x60(%rsp), %xmm0
ja 0x18184
movl %ebp, %ecx
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
imulq %r15, %rdx
incl %ebp
cmpq %rcx, %rdx
ja 0x1814c
jmp 0x1818b
movq 0x10(%rsp), %rax
xorl %ebx, %ebx
testq %rax, %rax
je 0x181a0
movq 0x20(%rsp), %rsi
subq %rax, %rsi
movq %rax, %rdi
callq 0xe450
testb %bl, %bl
je 0x17c22
xorpd %xmm0, %xmm0
leaq 0x70(%rsp), %r14
movapd %xmm0, (%r14)
movupd %xmm0, 0x18(%r14)
movq $0x0, 0x28(%r14)
movl $0x1, 0x30(%r14)
movabsq $0x2000000028, %rax     # imm = 0x2000000028
movq %rax, 0x10(%r14)
movq %r13, %rbx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2497a
movq 0x18(%rbx), %rbx
cmpq %r13, %rbx
jne 0x181dd
movl 0x78(%rsp), %eax
cmpl $0x4, %eax
jl 0x183f4
leaq 0x10(%rsp), %rbx
leaq 0xc8(%rsp), %rbp
leaq 0x70(%rsp), %rdi
callq 0x24a8e
movq %rax, %r14
movq (%rax), %r15
movq 0x10(%rax), %rax
movq 0x18(%r14), %rcx
movq %rax, 0x8(%rsp)
movq (%rax), %rsi
movq %rcx, 0x50(%rsp)
movq (%rcx), %rcx
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r15, %rdx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
je 0x1845f
movq 0x20(%rax), %rcx
cmpq %r15, 0x8(%rcx)
je 0x1825c
cmpq %r15, 0x10(%rcx)
jne 0x18287
movq 0x28(%rax), %rcx
cmpq %r15, 0x8(%rcx)
je 0x1826c
cmpq %r15, 0x10(%rcx)
jne 0x18287
movq 0x30(%rax), %rax
cmpq %r15, 0x8(%rax)
je 0x18285
cmpq %r15, 0x10(%rax)
movl $0x0, %ecx
cmovneq %rax, %rcx
jmp 0x18287
xorl %ecx, %ecx
movq 0x10(%r14), %rax
movq %rcx, 0x8(%rax)
movq 0x18(%r14), %rcx
movq %rcx, 0x18(%rax)
movq %rax, 0x10(%rcx)
movl $0x30, %esi
movq %r14, %rdi
callq 0xe450
addq $0x18, %r15
movq %r15, 0xb0(%rsp)
movb $0x1, %al
movl %eax, 0x40(%rsp)
testb $0x1, %al
movq 0x50(%rsp), %r14
cmovneq 0x8(%rsp), %r14
movq 0x10(%r14), %rax
movq 0x18(%r14), %rcx
movq (%rax), %r13
movq (%rcx), %r15
testb $0x2, 0x78(%r13)
jne 0x182ec
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r13, %rsi
callq *0x2b0(%rax)
testb $0x2, 0x78(%r15)
jne 0x18303
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r15, %rsi
callq *0x2b0(%rax)
leaq 0x18(%r13), %rsi
movq %rbx, %rdi
movq 0xb0(%rsp), %r12
movq %r12, %rdx
callq 0x3c78e
leaq 0x18(%r15), %rsi
movq %rbp, %rdi
movq %r12, %rdx
callq 0x3c78e
leaq 0xe0(%rsp), %rdi
movq %rbx, %rsi
movq %rbp, %rdx
callq 0x3d8fa
movq %rbp, %rsi
movq %rbx, %r12
movq %rbx, %rdi
callq 0x4bc63
movapd %xmm0, 0x60(%rsp)
movq (%r14), %rbx
testb $0x2, 0x78(%rbx)
jne 0x18369
movq (%rsp), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
callq *0x2b0(%rax)
addq $0x30, %rbx
leaq 0xe0(%rsp), %rdi
movq %rbx, %rsi
callq 0x3d252
movsd %xmm0, 0x30(%rsp)
addq $0x30, %r13
addq $0x30, %r15
movq %r13, %rdi
movq %r15, %rsi
callq 0x4bc63
movsd 0x48(%rsp), %xmm1
movapd 0x60(%rsp), %xmm3
subsd %xmm3, %xmm1
xorpd %xmm2, %xmm2
cmpltsd 0x30(%rsp), %xmm2
andpd %xmm2, %xmm1
andnpd %xmm3, %xmm2
orpd %xmm1, %xmm2
addsd %xmm0, %xmm2
movsd %xmm2, 0x28(%r14)
leaq 0x70(%rsp), %rdi
movq %r14, %rsi
callq 0x24b34
testb $0x1, 0x40(%rsp)
movl $0x0, %eax
movq %r12, %rbx
jne 0x182b6
movl 0x78(%rsp), %eax
cmpl $0x4, %eax
jge 0x1820b
cmpl $0x3, %eax
jne 0x1845f
leaq 0x70(%rsp), %rdi
callq 0x24a8e
movq %rax, %r14
movq (%rax), %rdx
movq 0x10(%rax), %rax
movq (%rax), %rsi
movq 0x18(%r14), %rax
movq (%rax), %rcx
movq (%rsp), %rdi
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movl $0x30, %esi
movq %r14, %rdi
callq 0xe450
leaq 0x70(%rsp), %rdi
callq 0x24a8e
movl $0x30, %esi
movq %rax, %rdi
callq 0xe450
leaq 0x70(%rsp), %rdi
callq 0x24a8e
movl $0x30, %esi
movq %rax, %rdi
callq 0xe450
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x17c22
callq 0xe5b0
jmp 0x17c22
jmp 0x18483
jmp 0x184ad
jmp 0x184ad
jmp 0x18483
jmp 0x184ad
jmp 0x184ad
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x184bf
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0xe450
jmp 0x184bf
jmp 0x184ad
jmp 0x184ad
jmp 0x184ad
jmp 0x184ad
jmp 0x184ad
jmp 0x184ad
jmp 0x184ad
movq %rax, %rbx
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x184bf
callq 0xe5b0
movq %rbx, %rdi
callq 0xe7e0
nop