// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::SplitEdge(gaps::R3MeshEdge*, gaps::R3Point const&, gaps::R3MeshEdge**, gaps::R3MeshEdge**)
R3MeshVertex *R3Mesh::
SplitEdge(R3MeshEdge *edge, const R3Point& point, R3MeshEdge **e0, R3MeshEdge **e1)
{
  // Create vertex at split point
  R3MeshVertex *vertex = CreateVertex(R3zero_point);

  // Get vertices on edge
  R3MeshVertex *v[2];
  v[0] = edge->vertex[0];
  v[1] = edge->vertex[1];

  // Get faces on edge
  R3MeshFace *f[2];
  f[0] = edge->face[0];
  f[1] = edge->face[1];

  // Get other edges and vertex on f[0]
  R3MeshEdge *ef[2][2] = { { NULL, NULL }, { NULL, NULL } };
  R3MeshVertex *vf[2] = { NULL, NULL };
  int m[2] = { 0, 0 };
  int s[2] = { 0, 0 };
  int c[2] = { 0, 0 };
  if (f[0]) {
    ef[0][0] = EdgeAcrossVertex(v[0], edge, f[0]);
    ef[0][1] = EdgeAcrossVertex(v[1], edge, f[0]);
    vf[0] = VertexAcrossEdge(ef[0][1], v[1]);
    assert(vf[0] == VertexAcrossEdge(ef[0][0], v[0]));
    m[0] = FaceMaterial(f[0]);
    s[0] = FaceSegment(f[0]);
    c[0] = FaceCategory(f[0]);
  }
  if (f[1]) {
    ef[1][0] = EdgeAcrossVertex(v[0], edge, f[1]);
    ef[1][1] = EdgeAcrossVertex(v[1], edge, f[1]);
    vf[1] = VertexAcrossEdge(ef[1][1], v[1]);
    assert(vf[1] == VertexAcrossEdge(ef[1][0], v[0]));
    m[1] = FaceMaterial(f[1]);
    s[1] = FaceSegment(f[1]);
    c[1] = FaceCategory(f[1]);
  }

  // Delete the edge and the two adjacent faces
  if (f[0]) DeleteFace(f[0]);
  if (f[1]) DeleteFace(f[1]);
  DeleteEdge(edge);

  // Create two new edges
  R3MeshEdge *e[2];
  e[0] = CreateEdge(v[0], vertex);
  e[1] = CreateEdge(vertex, v[1]);

  // Create two new faces on one side
  if (f[0]) {
    // Create edge splitting f[0]
    R3MeshEdge *es = CreateEdge(vertex, vf[0]);

    // Create new face on v[0] side of split
    assert((vf[0] != v[0]) && (vf[0] != vertex) && (v[0] != vertex));
    assert((ef[0][0] != e[0]) && (ef[0][0] != es) && (e[0] != es));
    R3MeshFace *f00 = CreateFace(vf[0], v[0], vertex, ef[0][0], e[0], es);
    SetFaceMaterial(f00, m[0]);
    SetFaceSegment(f00, s[0]);
    SetFaceCategory(f00, c[0]);

    // Create new face on v[1] side of split
    assert((es != e[1]) && (es != ef[0][1]) && (e[1] != ef[0][1]));
    R3MeshFace *f01 = CreateFace(vf[0], vertex, v[1], es, e[1], ef[0][1]);
    SetFaceMaterial(f01, m[0]);
    SetFaceSegment(f01, s[0]);
    SetFaceCategory(f01, c[0]);
  }

  // Create two new faces on other side
  if (f[1]) {
    // Create edge splitting f[1]
    R3MeshEdge *es = CreateEdge(vertex, vf[1]);
    
    // Create new face on v[1] side of split
    assert((vf[1] != v[1]) && (vf[1] != vertex) && (v[1] != vertex));
    assert((ef[1][1] != e[1]) && (ef[1][1] != es) && (e[1] != es));
    R3MeshFace *f10 = CreateFace(vf[1], v[1], vertex, ef[1][1], e[1], es);
    SetFaceMaterial(f10, m[1]);
    SetFaceSegment(f10, s[1]);
    SetFaceCategory(f10, c[1]);

    // Create new face on v[0] side of split
    assert((es != e[0]) && (es != ef[1][0]) && (e[0] != ef[1][0]));
    R3MeshFace *f11 = CreateFace(vf[1], vertex, v[0], es, e[0], ef[1][0]);
    SetFaceMaterial(f11, m[1]);
    SetFaceSegment(f11, s[1]);
    SetFaceCategory(f11, c[1]);
  }

  // Interpolate vertex properties
  RNScalar d0 = R3Distance(point, VertexPosition(v[0]));
  RNScalar d1 = R3Distance(point, VertexPosition(v[1]));
  RNScalar dsum = d0 + d1;
  if (RNIsPositive(dsum)) {
    d0 /= dsum;  d1 /= dsum;
    SetVertexTextureCoords(vertex, d1*VertexTextureCoords(v[0]) + d0*VertexTextureCoords(v[1])); 
    SetVertexColor(vertex, d1*VertexColor(v[0]) + d0*VertexColor(v[1])); 
  }

  // Set vertex position (also marks things in need of update)
  SetVertexPosition(vertex, point);

  // Return edges
  if (e0) *e0 = e[0];
  if (e1) *e1 = e[1];

  // Return vertex
  return vertex;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %r8, 0x98(%rsp)
movq %rcx, 0x90(%rsp)
movq %rdx, 0x68(%rsp)
movq %rsi, %r12
movq %rdi, %r13
movq (%rdi), %rax
leaq 0x4d0b16(%rip), %rsi    # 0x4e6a60
movq $0x0, 0x18(%rsp)
xorl %edx, %edx
callq *0x20(%rax)
movq %rax, %r15
movq 0x8(%r12), %rax
movq %rax, 0x8(%rsp)
movq 0x10(%r12), %rbp
movq 0x18(%r12), %rbx
movq 0x20(%r12), %r14
movl $0x0, %ecx
movl $0x0, %edx
movl $0x0, %esi
movl $0x0, %edi
movl $0x0, %eax
movl $0x0, %r8d
movq %r8, 0x58(%rsp)
testq %rbx, %rbx
je 0x15fdf
movq 0x8(%rsp), %rsi
movq %r12, %rdx
movq %rbx, %rcx
callq 0x13962
movq %rax, 0x58(%rsp)
movq %rbp, %rsi
movq %r12, %rdx
movq %rbx, %rcx
callq 0x13962
movq 0x8(%rax), %rdi
cmpq %rbp, %rdi
jne 0x15fcd
movq 0x10(%rax), %rdi
movl 0x98(%rbx), %esi
movl 0x9c(%rbx), %edx
movl 0xa0(%rbx), %ecx
movq %rdi, 0x78(%rsp)
movl %esi, 0x34(%rsp)
movl %edx, 0x38(%rsp)
movl %ecx, 0x3c(%rsp)
movq %rax, 0x80(%rsp)
testq %r14, %r14
je 0x1605b
movq 0x8(%rsp), %rsi
movq %r12, %rdx
movq %r14, %rcx
callq 0x13962
movq %rax, 0x50(%rsp)
movq %rbp, %rsi
movq %r12, %rdx
movq %r14, %rcx
callq 0x13962
movq 0x8(%rax), %rcx
cmpq %rbp, %rcx
jne 0x1602d
movq 0x10(%rax), %rcx
movq %rax, 0x40(%rsp)
movq %rcx, 0x48(%rsp)
movl 0x98(%r14), %eax
movl %eax, 0x14(%rsp)
movl 0x9c(%r14), %eax
movq %rax, 0x18(%rsp)
movl 0xa0(%r14), %eax
movl %eax, 0x10(%rsp)
jmp 0x16086
movl $0x0, 0x10(%rsp)
movl $0x0, 0x14(%rsp)
movq $0x0, 0x48(%rsp)
movq $0x0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
testq %rbx, %rbx
je 0x16098
movq (%r13), %rax
movq %r13, %rdi
movq %rbx, %rsi
callq *0x70(%rax)
testq %r14, %r14
je 0x160aa
movq (%r13), %rax
movq %r13, %rdi
movq %r14, %rsi
callq *0x70(%rax)
movq %r14, 0x88(%rsp)
movq (%r13), %rax
movq %r13, %rdi
movq %r12, %rsi
callq *0x68(%rax)
movq (%r13), %rax
movq %r13, %rdi
movq 0x8(%rsp), %r12
movq %r12, %rsi
movq %r15, %rdx
xorl %ecx, %ecx
callq *0x40(%rax)
movq %rax, %r14
movq (%r13), %rax
movq %r13, %rdi
movq %r15, %rsi
movq %rbp, %rdx
xorl %ecx, %ecx
callq *0x40(%rax)
testq %rbx, %rbx
movq %r14, 0x60(%rsp)
movq %rax, 0x28(%rsp)
movq %rbp, 0x20(%rsp)
je 0x161b7
movq (%r13), %rax
xorl %ebx, %ebx
movq %r13, %rdi
movq %r15, %rsi
movq 0x78(%rsp), %rbp
movq %rbp, %rdx
xorl %ecx, %ecx
callq *0x40(%rax)
movq %rax, 0x70(%rsp)
movq (%r13), %r10
movq %r13, %rdi
movq %rbp, %rsi
movq 0x8(%rsp), %rdx
movq %r15, %rcx
movq 0x58(%rsp), %r8
movq %r14, %r9
pushq %rbx
pushq %rax
callq *0x58(%r10)
addq $0x10, %rsp
movl 0x34(%rsp), %ebx
movl %ebx, 0x98(%rax)
movl 0x38(%rsp), %r12d
movl %r12d, 0x9c(%rax)
movl 0x3c(%rsp), %r14d
movl %r14d, 0xa0(%rax)
movq (%r13), %rax
movq %r13, %rdi
movq %rbp, %rsi
movq %r15, %rdx
movq 0x20(%rsp), %rcx
movq 0x70(%rsp), %r8
movq 0x28(%rsp), %r9
xorl %r10d, %r10d
pushq %r10
movq 0x10(%rsp), %rbp
pushq 0x88(%rsp)
callq *0x58(%rax)
addq $0x10, %rsp
movl %ebx, 0x98(%rax)
movl %r12d, 0x9c(%rax)
movq %rbp, %r12
movq 0x20(%rsp), %rbp
movl %r14d, 0xa0(%rax)
cmpq $0x0, 0x88(%rsp)
je 0x16279
movq (%r13), %rax
xorl %r14d, %r14d
movq %r13, %rdi
movq %r15, %rsi
movq 0x48(%rsp), %rbx
movq %rbx, %rdx
xorl %ecx, %ecx
callq *0x40(%rax)
movq %rax, 0x8(%rsp)
movq (%r13), %r10
movq %r13, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
movq %r15, %rcx
movq 0x40(%rsp), %r8
movq 0x28(%rsp), %r9
pushq %r14
pushq %rax
callq *0x58(%r10)
addq $0x10, %rsp
movq %r15, %rbp
movl 0x14(%rsp), %r15d
movl %r15d, 0x98(%rax)
movq 0x18(%rsp), %r14
movl %r14d, 0x9c(%rax)
movl 0x10(%rsp), %ecx
movl %ecx, 0xa0(%rax)
movq (%r13), %rax
movq %r13, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
movq %r12, %rcx
movq 0x8(%rsp), %r8
movq 0x60(%rsp), %r9
xorl %r10d, %r10d
pushq %r10
pushq 0x58(%rsp)
callq *0x58(%rax)
addq $0x10, %rsp
movl %r15d, 0x98(%rax)
movq %rbp, %r15
movq 0x20(%rsp), %rbp
movl %r14d, 0x9c(%rax)
movl 0x10(%rsp), %ecx
movl %ecx, 0xa0(%rax)
leaq 0x18(%r12), %rsi
movq 0x68(%rsp), %rbx
movq %rbx, %rdi
callq 0x49404
movsd %xmm0, 0x8(%rsp)
leaq 0x18(%rbp), %rsi
movq %rbx, %rdi
callq 0x49404
movsd 0x8(%rsp), %xmm2
movapd %xmm2, %xmm1
addsd %xmm0, %xmm2
leaq 0xcf8e6(%rip), %rax     # 0xe5b98
ucomisd (%rax), %xmm2
jbe 0x163c1
divsd %xmm2, %xmm1
movsd %xmm1, 0x8(%rsp)
divsd %xmm2, %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x48(%r12), %rsi
leaq 0xa0(%rsp), %rdi
callq 0x6834d
leaq 0x48(%rbp), %rsi
leaq 0xb8(%rsp), %r14
movq %r14, %rdi
movsd 0x8(%rsp), %xmm0
callq 0x6834d
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
leaq 0xa0(%rsp), %rsi
movq %r14, %rdx
callq 0x682bb
leaq 0x48(%r15), %rdi
movq %rbx, %rsi
callq 0x681de
movsd 0x58(%r12), %xmm0
movsd 0x18(%rsp), %xmm2
mulsd %xmm2, %xmm0
movsd 0x60(%r12), %xmm1
mulsd %xmm2, %xmm1
mulsd 0x68(%r12), %xmm2
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
callq 0x6f680
movsd 0x58(%rbp), %xmm0
movsd 0x8(%rsp), %xmm2
mulsd %xmm2, %xmm0
movsd 0x60(%rbp), %xmm1
mulsd %xmm2, %xmm1
mulsd 0x68(%rbp), %xmm2
leaq 0xb8(%rsp), %r14
movq %r14, %rdi
callq 0x6f680
movsd (%rbx), %xmm0
movsd 0x8(%rbx), %xmm1
addsd (%r14), %xmm0
addsd 0x8(%r14), %xmm1
movsd 0x10(%rbx), %xmm2
addsd 0x10(%r14), %xmm2
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
callq 0x6f680
movq %r15, %rdi
addq $0x58, %rdi
movq %rbx, %rsi
callq 0x6f712
movq %r13, %rdi
movq %r15, %rsi
movq 0x68(%rsp), %rdx
callq 0x13858
movq 0x90(%rsp), %rax
testq %rax, %rax
je 0x163e6
movq 0x60(%rsp), %rcx
movq %rcx, (%rax)
movq 0x98(%rsp), %rax
testq %rax, %rax
movq 0x28(%rsp), %rcx
je 0x163fb
movq %rcx, (%rax)
movq %r15, %rax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq