// File: tomfunkhouser[P]gaps/apps/msh2msh/msh2msh.cpp
// Function: CopyFromSource(gaps::R3Mesh*, char const*)
static int
CopyFromSource(R3Mesh *mesh, const char *source_mesh_name)
{
  // Read source mesh
  R3Mesh source_mesh;
  if (!source_mesh.ReadFile(source_mesh_name)) return 0;

  // Create kdtree
  R3MeshSearchTree kdtree(&source_mesh);
  
  // Copy stuff from source mesh
  if (copy_colors) {
    // Copy info from closest vertex (no interpolation)
    for (int i = 0; i < mesh->NVertices(); i++) {
      R3MeshVertex *vertex = mesh->Vertex(i);
      mesh->SetVertexColor(vertex, RNblack_rgb);
      const R3Point& position = mesh->VertexPosition(vertex);

      // Search kdtree
      R3MeshIntersection closest;
      kdtree.FindClosest(position, closest);
      if (closest.type == R3_MESH_VERTEX_TYPE) {
        mesh->SetVertexColor(vertex, source_mesh.VertexColor(closest.vertex));
      }
      else if (closest.type == R3_MESH_EDGE_TYPE) {
        R3Span span = mesh->EdgeSpan(closest.edge);
        RNScalar t = span.T(position);
        int k = (t < 0.5 * span.Length()) ?  0 : 1;
        R3MeshVertex *source_vertex = source_mesh.VertexOnEdge(closest.edge, k);
        mesh->SetVertexColor(vertex, source_mesh.VertexColor(source_vertex));
      }
      else if (closest.type == R3_MESH_FACE_TYPE) {
        R3Point b = source_mesh.FaceBarycentric(closest.face, position);
        int k = b.Vector().MaxDimension();
        R3MeshVertex *source_vertex = source_mesh.VertexOnFace(closest.face, k);
        mesh->SetVertexColor(vertex, source_mesh.VertexColor(source_vertex));
      }
    }
  }
  else if (copy_categories || copy_segments || copy_materials) {
    // Copy info from closest face
    for (int i = 0; i < mesh->NFaces(); i++) {
      R3MeshFace *face = mesh->Face(i);
      const R3Point& position = mesh->FaceCentroid(face);

      // Search kdtree
      R3MeshIntersection closest;
      kdtree.FindClosest(position, closest);
      if (copy_categories) mesh->SetFaceCategory(face, source_mesh.FaceCategory(closest.face));
      if (copy_segments) mesh->SetFaceSegment(face, source_mesh.FaceSegment(closest.face));
      if (copy_materials) mesh->SetFaceMaterial(face, source_mesh.FaceMaterial(closest.face));
    }
  }

  // Return success
  return 1;
}

// Assembly:
subq $0x3d8, %rsp            # imm = 0x3D8
movq %rdi, 0x3c8(%rsp)
movq %rsi, 0x3c0(%rsp)
leaq 0x288(%rsp), %rdi
movq %rdi, 0xe0(%rsp)
callq 0x32880
movq 0xe0(%rsp), %rdi
movq 0x3c0(%rsp), %rsi
callq 0x4a8e0
movl %eax, 0xec(%rsp)
jmp 0x1580a
movl 0xec(%rsp), %eax
cmpl $0x0, %eax
jne 0x1584a
movl $0x0, 0x3d4(%rsp)
movl $0x1, 0x278(%rsp)
jmp 0x15e60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x280(%rsp)
movl %eax, 0x27c(%rsp)
jmp 0x15e7c
leaq 0x260(%rsp), %rdi
leaq 0x288(%rsp), %rsi
callq 0x17000
jmp 0x15861
cmpl $0x0, 0x14b4b8(%rip)    # 0x160d20
je 0x15c39
movl $0x0, 0x25c(%rsp)
movl 0x25c(%rsp), %eax
movl %eax, 0xdc(%rsp)
movq 0x3c8(%rsp), %rdi
callq 0x16630
movl %eax, %ecx
movl 0xdc(%rsp), %eax
cmpl %ecx, %eax
jge 0x15c34
movq 0x3c8(%rsp), %rdi
movl 0x25c(%rsp), %esi
callq 0x16de0
movq %rax, 0xd0(%rsp)
jmp 0x158c3
movq 0xd0(%rsp), %rax
movq %rax, 0x250(%rsp)
movq 0x3c8(%rsp), %rdi
movq 0x250(%rsp), %rsi
leaq 0x14df5e(%rip), %rdx    # 0x163848
callq 0x16e10
jmp 0x158f1
movq 0x3c8(%rsp), %rdi
movq 0x250(%rsp), %rsi
callq 0x16770
movq %rax, 0x248(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x16e40
jmp 0x1591d
movq 0x248(%rsp), %rsi
leaq 0x14b354(%rip), %rax    # 0x160c80
movsd (%rax), %xmm1
xorl %eax, %eax
movl %eax, %r8d
leaq 0x260(%rsp), %rdi
leaq 0x208(%rsp), %rdx
xorps %xmm0, %xmm0
movq %r8, %rcx
callq 0x1a3f0
jmp 0x15952
cmpl $0x1, 0x208(%rsp)
jne 0x159e9
movq 0x3c8(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0x210(%rsp), %rsi
leaq 0x288(%rsp), %rdi
callq 0x16e60
movq %rax, 0xc8(%rsp)
jmp 0x1599f
movq 0xc8(%rsp), %rdx
movq 0xc0(%rsp), %rsi
movq 0xb8(%rsp), %rdi
callq 0x16e10
jmp 0x159be
jmp 0x15c1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x280(%rsp)
movl %eax, 0x27c(%rsp)
leaq 0x260(%rsp), %rdi
callq 0x171c0
jmp 0x15e7c
cmpl $0x2, 0x208(%rsp)
jne 0x15b3a
movq 0x3c8(%rsp), %rsi
movq 0x218(%rsp), %rdx
leaq 0x1b8(%rsp), %rdi
callq 0x16e80
jmp 0x15a16
movq 0x248(%rsp), %rsi
leaq 0x1b8(%rsp), %rdi
callq 0x77300
movsd %xmm0, 0xb0(%rsp)
jmp 0x15a36
movsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0x1b0(%rsp)
movsd 0x1b0(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
leaq 0x1b8(%rsp), %rdi
callq 0x16ed0
movsd %xmm0, 0xa8(%rsp)
jmp 0x15a72
movsd 0xa0(%rsp), %xmm1
movsd 0xa8(%rsp), %xmm0
movsd 0x1105ac(%rip), %xmm2   # 0x126038
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
setbe %al
movzbl %al, %eax
movl %eax, 0x1ac(%rsp)
movq 0x218(%rsp), %rsi
movl 0x1ac(%rsp), %edx
leaq 0x288(%rsp), %rdi
callq 0x16ee0
movq %rax, 0x98(%rsp)
jmp 0x15ac7
movq 0x98(%rsp), %rax
movq %rax, 0x1a0(%rsp)
movq 0x3c8(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x1a0(%rsp), %rsi
leaq 0x288(%rsp), %rdi
callq 0x16e60
movq %rax, 0x90(%rsp)
jmp 0x15b16
movq 0x90(%rsp), %rdx
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdi
callq 0x16e10
jmp 0x15b35
jmp 0x15c1a
cmpl $0x3, 0x208(%rsp)
jne 0x15c18
movq 0x220(%rsp), %rdx
movq 0x248(%rsp), %rcx
leaq 0x188(%rsp), %rdi
leaq 0x288(%rsp), %rsi
callq 0x364f0
jmp 0x15b6f
leaq 0x168(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x16470
jmp 0x15b86
leaq 0x168(%rsp), %rdi
callq 0x79980
movl %eax, 0x7c(%rsp)
jmp 0x15b99
movl 0x7c(%rsp), %eax
movl %eax, 0x184(%rsp)
movq 0x220(%rsp), %rsi
movl 0x184(%rsp), %edx
leaq 0x288(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x16750
movq 0x58(%rsp), %rdi
movq %rax, 0x160(%rsp)
movq 0x3c8(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x160(%rsp), %rsi
callq 0x16e60
movq %rax, 0x70(%rsp)
jmp 0x15c00
movq 0x70(%rsp), %rdx
movq 0x68(%rsp), %rsi
movq 0x60(%rsp), %rdi
callq 0x16e10
jmp 0x15c16
jmp 0x15c18
jmp 0x15c1a
jmp 0x15c1c
jmp 0x15c1e
movl 0x25c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x25c(%rsp)
jmp 0x15879
jmp 0x15e3d
cmpl $0x0, 0x14b0e4(%rip)    # 0x160d24
jne 0x15c58
cmpl $0x0, 0x14b0df(%rip)    # 0x160d28
jne 0x15c58
cmpl $0x0, 0x14b0da(%rip)    # 0x160d2c
je 0x15e3b
movl $0x0, 0x15c(%rsp)
movl 0x15c(%rsp), %eax
movl %eax, 0x54(%rsp)
movq 0x3c8(%rsp), %rdi
callq 0x164b0
movl %eax, %ecx
movl 0x54(%rsp), %eax
cmpl %ecx, %eax
jge 0x15e39
movq 0x3c8(%rsp), %rdi
movl 0x15c(%rsp), %esi
callq 0x164d0
movq %rax, 0x48(%rsp)
jmp 0x15ca4
movq 0x48(%rsp), %rax
movq %rax, 0x150(%rsp)
movq 0x3c8(%rsp), %rsi
movq 0x150(%rsp), %rdx
leaq 0x130(%rsp), %rdi
callq 0x33a00
jmp 0x15cd0
leaq 0x130(%rsp), %rax
movq %rax, 0x148(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x16e40
jmp 0x15cef
movq 0x148(%rsp), %rsi
leaq 0x14af82(%rip), %rax    # 0x160c80
movsd (%rax), %xmm1
xorl %eax, %eax
movl %eax, %r8d
leaq 0x260(%rsp), %rdi
leaq 0xf0(%rsp), %rdx
xorps %xmm0, %xmm0
movq %r8, %rcx
callq 0x1a3f0
jmp 0x15d24
cmpl $0x0, 0x14aff9(%rip)    # 0x160d24
je 0x15d79
movq 0x3c8(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x108(%rsp), %rsi
leaq 0x288(%rsp), %rdi
callq 0x16f20
movl %eax, 0x44(%rsp)
jmp 0x15d62
movl 0x44(%rsp), %edx
movq 0x38(%rsp), %rsi
movq 0x30(%rsp), %rdi
callq 0x16f00
jmp 0x15d77
jmp 0x15d79
cmpl $0x0, 0x14afa8(%rip)    # 0x160d28
je 0x15dce
movq 0x3c8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x108(%rsp), %rsi
leaq 0x288(%rsp), %rdi
callq 0x16f60
movl %eax, 0x2c(%rsp)
jmp 0x15db7
movl 0x2c(%rsp), %edx
movq 0x20(%rsp), %rsi
movq 0x18(%rsp), %rdi
callq 0x16f40
jmp 0x15dcc
jmp 0x15dce
cmpl $0x0, 0x14af57(%rip)    # 0x160d2c
je 0x15e21
movq 0x3c8(%rsp), %rax
movq %rax, (%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x108(%rsp), %rsi
leaq 0x288(%rsp), %rdi
callq 0x16fa0
movl %eax, 0x14(%rsp)
jmp 0x15e0b
movl 0x14(%rsp), %edx
movq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x16f80
jmp 0x15e1f
jmp 0x15e21
jmp 0x15e23
movl 0x15c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x15c(%rsp)
jmp 0x15c63
jmp 0x15e3b
jmp 0x15e3d
movl $0x1, 0x3d4(%rsp)
movl $0x1, 0x278(%rsp)
leaq 0x260(%rsp), %rdi
callq 0x171c0
leaq 0x288(%rsp), %rdi
callq 0x33780
movl 0x3d4(%rsp), %eax
addq $0x3d8, %rsp            # imm = 0x3D8
retq
leaq 0x288(%rsp), %rdi
callq 0x33780
movq 0x280(%rsp), %rdi
callq 0xf820
nopw %cs:(%rax,%rax)