// File: tomfunkhouser[P]gaps/apps/mshsegment/mshsegment.cpp
// Function: RefineBoundaries(gaps::R3Mesh*)
static int
RefineBoundaries(R3Mesh *mesh)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();

  // Refine boundaries
  RNBoolean done = FALSE;
  while (!done) {
    done = TRUE;
    for (int i = 0; i < mesh->NFaces(); i++) {
      R3MeshFace *face = mesh->Face(i);
      R3MeshEdge *edge0 = mesh->EdgeOnFace(face, 0);
      R3MeshEdge *edge1 = mesh->EdgeOnFace(face, 1);
      R3MeshEdge *edge2 = mesh->EdgeOnFace(face, 2);
      R3MeshFace *face0 = mesh->FaceAcrossEdge(edge0, face);
      R3MeshFace *face1 = mesh->FaceAcrossEdge(edge1, face);
      R3MeshFace *face2 = mesh->FaceAcrossEdge(edge2, face);
      if (!face0 || !face1 || !face2) continue;
      int segment = mesh->FaceSegment(face);
      int segment0 = mesh->FaceSegment(face0);
      int segment1 = mesh->FaceSegment(face1);
      int segment2 = mesh->FaceSegment(face2);
      R3Vector normal = mesh->FaceNormal(face);
      R3Vector normal0 = mesh->FaceNormal(face0);
      R3Vector normal1 = mesh->FaceNormal(face1);
      R3Vector normal2 = mesh->FaceNormal(face2);
      RNAngle angle0 = R3InteriorAngle(normal, normal0);
      RNAngle angle1 = R3InteriorAngle(normal, normal1);
      RNAngle angle2 = R3InteriorAngle(normal, normal2);
      if (angle0 > options.max_pair_normal_angle) segment0 = -1;
      if (angle1 > options.max_pair_normal_angle) segment1 = -1;
      if (angle2 > options.max_pair_normal_angle) segment2 = -1;
      if ((segment != segment0) && (segment0 >= 0) && (segment1 >= 0) && (segment0 == segment1)) {
        mesh->SetFaceSegment(face, segment0);
        done = FALSE;
      }
      else if ((segment != segment0) && (segment0 >= 0) && (segment2 >= 0) && (segment0 == segment2)) {
        mesh->SetFaceSegment(face, segment0);
        done = FALSE;
      }
      else if ((segment != segment1) && (segment1 >= 0) && (segment2 >= 0) && (segment1 == segment2)) {
        mesh->SetFaceSegment(face, segment1);
        done = FALSE;
      }
    }
  }
  
  // Print statistics
  if (print_verbose) {
    printf("Refined boundaries ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    fflush(stdout);
  }

  // Return success
  return 1;
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xe0(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xa5c50
leaq 0xd0(%rsp), %rdi
callq 0x12040
movl $0x0, 0xcc(%rsp)
cmpl $0x0, 0xcc(%rsp)
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x10d0a
jmp 0x1111b
movl $0x1, 0xcc(%rsp)
movl $0x0, 0xc8(%rsp)
movl 0xc8(%rsp), %eax
movl %eax, 0x4(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x12060
movl %eax, %ecx
movl 0x4(%rsp), %eax
cmpl %ecx, %eax
jge 0x11116
movq 0xe0(%rsp), %rdi
movl 0xc8(%rsp), %esi
callq 0x12080
movq %rax, 0xc0(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
xorl %edx, %edx
callq 0x13350
movq %rax, 0xb8(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movl $0x1, %edx
callq 0x13350
movq %rax, 0xb0(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movl $0x2, %edx
callq 0x13350
movq %rax, 0xa8(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xb8(%rsp), %rsi
movq 0xc0(%rsp), %rdx
callq 0x132e0
movq %rax, 0xa0(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xb0(%rsp), %rsi
movq 0xc0(%rsp), %rdx
callq 0x132e0
movq %rax, 0x98(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
movq 0xc0(%rsp), %rdx
callq 0x132e0
movq %rax, 0x90(%rsp)
cmpq $0x0, 0xa0(%rsp)
je 0x10e55
cmpq $0x0, 0x98(%rsp)
je 0x10e55
cmpq $0x0, 0x90(%rsp)
jne 0x10e5a
jmp 0x11100
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
callq 0x120b0
movl %eax, 0x8c(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x120b0
movl %eax, 0x88(%rsp)
movq 0xe0(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x120b0
movl %eax, 0x84(%rsp)
movq 0xe0(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x120b0
movl %eax, 0x80(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
callq 0x121c0
movq %rax, %rsi
leaq 0x68(%rsp), %rdi
callq 0x81610
movq 0xe0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x121c0
movq %rax, %rsi
leaq 0x50(%rsp), %rdi
callq 0x81610
movq 0xe0(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x121c0
movq %rax, %rsi
leaq 0x38(%rsp), %rdi
callq 0x81610
movq 0xe0(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x121c0
movq %rax, %rsi
leaq 0x20(%rsp), %rdi
callq 0x81610
leaq 0x68(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x361c0
movsd %xmm0, 0x18(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x361c0
movsd %xmm0, 0x10(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x361c0
movsd %xmm0, 0x8(%rsp)
movsd 0x18(%rsp), %xmm0
ucomisd 0xc0cb9(%rip), %xmm0    # 0xd1c58
jbe 0x10fac
movl $0xffffffff, 0x88(%rsp) # imm = 0xFFFFFFFF
movsd 0x10(%rsp), %xmm0
ucomisd 0xc0c9e(%rip), %xmm0    # 0xd1c58
jbe 0x10fc7
movl $0xffffffff, 0x84(%rsp) # imm = 0xFFFFFFFF
movsd 0x8(%rsp), %xmm0
ucomisd 0xc0c83(%rip), %xmm0    # 0xd1c58
jbe 0x10fe2
movl $0xffffffff, 0x80(%rsp) # imm = 0xFFFFFFFF
movl 0x8c(%rsp), %eax
cmpl 0x88(%rsp), %eax
je 0x11042
cmpl $0x0, 0x88(%rsp)
jl 0x11042
cmpl $0x0, 0x84(%rsp)
jl 0x11042
movl 0x88(%rsp), %eax
cmpl 0x84(%rsp), %eax
jne 0x11042
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movl 0x88(%rsp), %edx
callq 0x120f0
movl $0x0, 0xcc(%rsp)
jmp 0x110fe
movl 0x8c(%rsp), %eax
cmpl 0x88(%rsp), %eax
je 0x1109f
cmpl $0x0, 0x88(%rsp)
jl 0x1109f
cmpl $0x0, 0x80(%rsp)
jl 0x1109f
movl 0x88(%rsp), %eax
cmpl 0x80(%rsp), %eax
jne 0x1109f
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movl 0x88(%rsp), %edx
callq 0x120f0
movl $0x0, 0xcc(%rsp)
jmp 0x110fc
movl 0x8c(%rsp), %eax
cmpl 0x84(%rsp), %eax
je 0x110fa
cmpl $0x0, 0x84(%rsp)
jl 0x110fa
cmpl $0x0, 0x80(%rsp)
jl 0x110fa
movl 0x84(%rsp), %eax
cmpl 0x80(%rsp), %eax
jne 0x110fa
movq 0xe0(%rsp), %rdi
movq 0xc0(%rsp), %rsi
movl 0x84(%rsp), %edx
callq 0x120f0
movl $0x0, 0xcc(%rsp)
jmp 0x110fc
jmp 0x110fe
jmp 0x11100
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0x10d20
jmp 0x10cf4
cmpl $0x0, 0xc0ba6(%rip)     # 0xd1cc8
je 0x1115c
leaq 0x9a1dd(%rip), %rdi     # 0xab308
movb $0x0, %al
callq 0xd070
leaq 0xd0(%rsp), %rdi
callq 0xa5d10
leaq 0x9a0d9(%rip), %rdi     # 0xab21f
movb $0x1, %al
callq 0xd070
movq 0xbfe4c(%rip), %rax     # 0xd0fa0
movq (%rax), %rdi
callq 0xd4b0
movl $0x1, %eax
addq $0xe8, %rsp
retq
nopl (%rax)