// File: /workspace/github_cpp_makefile_star2_O3/hzeller[P]gcode-multi-shell-extrude/third_party/clipper.cpp
// Function: ClipperLib::Clipper::IntersectEdges(ClipperLib::TEdge*, ClipperLib::TEdge*, ClipperLib::IntPoint const&, bool)
void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
     const IntPoint &Pt, bool protect)
{
  //e1 will be to the Left of e2 BELOW the intersection. Therefore e1 is before
  //e2 in AEL except when e1 is being inserted at the intersection point ...
  bool e1stops = !protect &&  !e1->NextInLML &&
    e1->Top.X == Pt.X && e1->Top.Y == Pt.Y;
  bool e2stops = !protect &&  !e2->NextInLML &&
    e2->Top.X == Pt.X && e2->Top.Y == Pt.Y;
  bool e1Contributing = ( e1->OutIdx >= 0 );
  bool e2Contributing = ( e2->OutIdx >= 0 );

#ifdef use_lines
  //if either edge is on an OPEN path ...
  if (e1->WindDelta == 0 || e2->WindDelta == 0)
  {
    //ignore subject-subject open path intersections UNLESS they
    //are both open paths, AND they are both 'contributing maximas' ...
    if (e1->WindDelta == 0 && e2->WindDelta == 0)
    {
      if ((e1stops || e2stops) && e1Contributing && e2Contributing)
        AddLocalMaxPoly(e1, e2, Pt);
    }

    //if intersecting a subj line with a subj poly ...
    else if (e1->PolyTyp == e2->PolyTyp && 
      e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
    {
      if (e1->WindDelta == 0)
      {
        if (e2Contributing)
        {
          AddOutPt(e1, Pt);
          if (e1Contributing) e1->OutIdx = Unassigned;
        }
      }
      else
      {
        if (e1Contributing)
        {
          AddOutPt(e2, Pt);
          if (e2Contributing) e2->OutIdx = Unassigned;
        }
      }
    }
    else if (e1->PolyTyp != e2->PolyTyp)
    {
      //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
      if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && 
        (m_ClipType != ctUnion || e2->WindCnt2 == 0))
      {
        AddOutPt(e1, Pt);
        if (e1Contributing) e1->OutIdx = Unassigned;
      }
      else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && 
        (m_ClipType != ctUnion || e1->WindCnt2 == 0))
      {
        AddOutPt(e2, Pt);
        if (e2Contributing) e2->OutIdx = Unassigned;
      }
    }

    if (e1stops)
      if (e1->OutIdx < 0) DeleteFromAEL(e1);
      else throw clipperException("Error intersecting polylines");
    if (e2stops) 
      if (e2->OutIdx < 0) DeleteFromAEL(e2);
      else throw clipperException("Error intersecting polylines");
    return;
  }
#endif

  //update winding counts...
  //assumes that e1 will be to the Right of e2 ABOVE the intersection
  if ( e1->PolyTyp == e2->PolyTyp )
  {
    if ( IsEvenOddFillType( *e1) )
    {
      int oldE1WindCnt = e1->WindCnt;
      e1->WindCnt = e2->WindCnt;
      e2->WindCnt = oldE1WindCnt;
    } else
    {
      if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt;
      else e1->WindCnt += e2->WindDelta;
      if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt;
      else e2->WindCnt -= e1->WindDelta;
    }
  } else
  {
    if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta;
    else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0;
    if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta;
    else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0;
  }

  PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
  if (e1->PolyTyp == ptSubject)
  {
    e1FillType = m_SubjFillType;
    e1FillType2 = m_ClipFillType;
  } else
  {
    e1FillType = m_ClipFillType;
    e1FillType2 = m_SubjFillType;
  }
  if (e2->PolyTyp == ptSubject)
  {
    e2FillType = m_SubjFillType;
    e2FillType2 = m_ClipFillType;
  } else
  {
    e2FillType = m_ClipFillType;
    e2FillType2 = m_SubjFillType;
  }

  cInt e1Wc, e2Wc;
  switch (e1FillType)
  {
    case pftPositive: e1Wc = e1->WindCnt; break;
    case pftNegative: e1Wc = -e1->WindCnt; break;
    default: e1Wc = Abs(e1->WindCnt);
  }
  switch(e2FillType)
  {
    case pftPositive: e2Wc = e2->WindCnt; break;
    case pftNegative: e2Wc = -e2->WindCnt; break;
    default: e2Wc = Abs(e2->WindCnt);
  }

  if ( e1Contributing && e2Contributing )
  {
    if ( e1stops || e2stops || 
      (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
      (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
        AddLocalMaxPoly(e1, e2, Pt); 
    else
    {
      AddOutPt(e1, Pt);
      AddOutPt(e2, Pt);
      SwapSides( *e1 , *e2 );
      SwapPolyIndexes( *e1 , *e2 );
    }
  }
  else if ( e1Contributing )
  {
    if (e2Wc == 0 || e2Wc == 1) 
    {
      AddOutPt(e1, Pt);
      SwapSides(*e1, *e2);
      SwapPolyIndexes(*e1, *e2);
    }
  }
  else if ( e2Contributing )
  {
    if (e1Wc == 0 || e1Wc == 1) 
    {
      AddOutPt(e2, Pt);
      SwapSides(*e1, *e2);
      SwapPolyIndexes(*e1, *e2);
    }
  } 
  else if ( (e1Wc == 0 || e1Wc == 1) && 
    (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops )
  {
    //neither edge is currently contributing ...

    cInt e1Wc2, e2Wc2;
    switch (e1FillType2)
    {
      case pftPositive: e1Wc2 = e1->WindCnt2; break;
      case pftNegative : e1Wc2 = -e1->WindCnt2; break;
      default: e1Wc2 = Abs(e1->WindCnt2);
    }
    switch (e2FillType2)
    {
      case pftPositive: e2Wc2 = e2->WindCnt2; break;
      case pftNegative: e2Wc2 = -e2->WindCnt2; break;
      default: e2Wc2 = Abs(e2->WindCnt2);
    }

    if (e1->PolyTyp != e2->PolyTyp)
        AddLocalMinPoly(e1, e2, Pt);
    else if (e1Wc == 1 && e2Wc == 1)
      switch( m_ClipType ) {
        case ctIntersection:
          if (e1Wc2 > 0 && e2Wc2 > 0)
            AddLocalMinPoly(e1, e2, Pt);
          break;
        case ctUnion:
          if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
            AddLocalMinPoly(e1, e2, Pt);
          break;
        case ctDifference:
          if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
              ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
                AddLocalMinPoly(e1, e2, Pt);
          break;
        case ctXor:
          AddLocalMinPoly(e1, e2, Pt);
      }
    else
      SwapSides( *e1, *e2 );
  }

  if(  (e1stops != e2stops) &&
    ( (e1stops && (e1->OutIdx >= 0)) || (e2stops && (e2->OutIdx >= 0)) ) )
  {
    SwapSides( *e1, *e2 );
    SwapPolyIndexes( *e1, *e2 );
  }

  //finally, delete any non-contributing maxima edges  ...
  if( e1stops ) DeleteFromAEL( e1 );
  if( e2stops ) DeleteFromAEL( e2 );
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %r12
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
testl %r8d, %r8d
je 0xc5c3
xorl %r13d, %r13d
jmp 0xc606
cmpq $0x0, 0x70(%r15)
jne 0xc5e3
movq 0x20(%r15), %rax
cmpq (%r12), %rax
jne 0xc5e3
movq 0x28(%r15), %rax
cmpq 0x8(%r12), %rax
sete %r13b
jmp 0xc5e6
xorl %r13d, %r13d
cmpq $0x0, 0x70(%rbx)
jne 0xc606
movq 0x20(%rbx), %rax
cmpq (%r12), %rax
jne 0xc606
movq 0x28(%rbx), %rax
cmpq 0x8(%r12), %rax
sete %bpl
jmp 0xc608
xorl %ebp, %ebp
movl 0x48(%r15), %eax
movl 0x5c(%r15), %esi
movl 0x48(%rbx), %ecx
movl 0x5c(%rbx), %edx
xorl %edi, %edi
cmpl %ecx, %eax
jne 0xc655
testl %eax, %eax
sete %dil
cmpl $0x0, 0xb4(%r14,%rdi,4)
movl 0x54(%r15), %edi
je 0xc66f
movl 0x50(%rbx), %r8d
addl %edi, %r8d
negl %edi
testl %r8d, %r8d
cmovnel %r8d, %edi
movl %edi, 0x54(%r15)
movl 0x54(%rbx), %edi
movl %edi, %r8d
subl 0x50(%r15), %r8d
jne 0xc6b6
negl %edi
jmp 0xc677
testl %ecx, %ecx
sete %dil
cmpl $0x0, 0xb4(%r14,%rdi,4)
je 0xc67c
movl 0x50(%rbx), %edi
addl %edi, 0x58(%r15)
jmp 0xc68b
movl 0x54(%rbx), %r8d
movl %r8d, 0x54(%r15)
movl %edi, 0x54(%rbx)
jmp 0xc6ba
xorl %edi, %edi
cmpl $0x0, 0x58(%r15)
sete %dil
movl %edi, 0x58(%r15)
xorl %edi, %edi
testl %eax, %eax
sete %dil
cmpl $0x0, 0xb4(%r14,%rdi,4)
je 0xc6a7
movl 0x50(%r15), %edi
subl %edi, 0x58(%rbx)
jmp 0xc6ba
xorl %edi, %edi
cmpl $0x0, 0x58(%rbx)
sete %dil
movl %edi, 0x58(%rbx)
jmp 0xc6ba
movl %r8d, 0x54(%rbx)
testl %eax, %eax
movl 0xb4(%r14), %r11d
movl 0xb8(%r14), %edi
movl %edi, %r10d
cmovel %r11d, %r10d
movl %r11d, %r8d
cmovel %edi, %r8d
testl %ecx, %ecx
movl %edi, %r9d
cmovel %r11d, %r9d
cmovel %edi, %r11d
movslq 0x54(%r15), %rdi
cmpl $0x3, %r8d
je 0xc701
cmpl $0x2, %r8d
je 0xc706
movl %edi, %r8d
negl %r8d
cmovnsl %r8d, %edi
jmp 0xc706
negl %edi
movslq %edi, %rdi
movslq 0x54(%rbx), %r8
cmpl $0x3, %r11d
je 0xc722
cmpl $0x2, %r11d
je 0xc728
movl %r8d, %r11d
negl %r11d
cmovnsl %r11d, %r8d
jmp 0xc728
negl %r8d
movslq %r8d, %r8
movl %esi, %r11d
orl %edx, %r11d
jns 0xc746
testl %esi, %esi
js 0xc77b
cmpq $0x1, %r8
ja 0xc7c3
movq %r14, %rdi
movq %r15, %rsi
jmp 0xc79f
movl %r13d, %edx
orb %bpl, %dl
testb $0x1, %dl
jne 0xc768
cmpq $0x1, %rdi
ja 0xc768
cmpq $0x1, %r8
ja 0xc768
cmpl %ecx, %eax
je 0xc78b
cmpl $0x3, 0x68(%r14)
je 0xc78b
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
movq %r12, %rcx
callq 0xc12e
jmp 0xc7c3
testl %edx, %edx
js 0xc8ab
cmpq $0x1, %rdi
jbe 0xc799
jmp 0xc7c3
movq %r14, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0xbfae
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0xbfae
movl 0x4c(%r15), %eax
movl 0x4c(%rbx), %ecx
movl %ecx, 0x4c(%r15)
movl %eax, 0x4c(%rbx)
movl 0x5c(%r15), %eax
movl 0x5c(%rbx), %ecx
movl %ecx, 0x5c(%r15)
movl %eax, 0x5c(%rbx)
cmpb %bpl, %r13b
je 0xc7ff
testb %r13b, %r13b
je 0xc7da
movl 0x5c(%r15), %eax
testl %eax, %eax
js 0xc7da
movl 0x5c(%rbx), %ecx
jmp 0xc7ea
testb %bpl, %bpl
je 0xc7ff
movl 0x5c(%rbx), %ecx
testl %ecx, %ecx
js 0xc7ff
movl 0x5c(%r15), %eax
movl 0x4c(%r15), %edx
movl 0x4c(%rbx), %esi
movl %esi, 0x4c(%r15)
movl %edx, 0x4c(%rbx)
movl %ecx, 0x5c(%r15)
movl %eax, 0x5c(%rbx)
testb %r13b, %r13b
je 0xc84e
movq 0x78(%r15), %rax
movq 0x80(%r15), %rcx
testq %rcx, %rcx
jne 0xc822
testq %rax, %rax
jne 0xc822
cmpq %r15, 0xa0(%r14)
jne 0xc84e
addq $0x78, %r15
leaq 0xa0(%r14), %rdx
leaq 0x78(%rcx), %rsi
testq %rcx, %rcx
cmovneq %rsi, %rdx
movq %rax, (%rdx)
testq %rax, %rax
je 0xc847
movq %rcx, 0x80(%rax)
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
testb %bpl, %bpl
je 0xc89c
movq 0x78(%rbx), %rax
movq 0x80(%rbx), %rcx
testq %rcx, %rcx
jne 0xc871
testq %rax, %rax
jne 0xc871
cmpq %rbx, 0xa0(%r14)
jne 0xc89c
addq $0x78, %rbx
addq $0xa0, %r14
leaq 0x78(%rcx), %rdx
testq %rcx, %rcx
cmoveq %r14, %rdx
movq %rax, (%rdx)
testq %rax, %rax
je 0xc896
movq %rcx, 0x80(%rax)
xorps %xmm0, %xmm0
movups %xmm0, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpq $0x1, %rdi
ja 0xc7c3
cmpq $0x2, %r8
setae %dl
movl %r13d, %esi
orb %bpl, %sil
orb %dl, %sil
testb $0x1, %sil
jne 0xc7c3
movslq 0x58(%r15), %rdx
cmpl $0x3, %r10d
je 0xc8e8
cmpl $0x2, %r10d
je 0xc8ed
movl %edx, %esi
negl %esi
cmovnsl %esi, %edx
jmp 0xc8ed
negl %edx
movslq %edx, %rdx
movslq 0x58(%rbx), %rsi
cmpl $0x3, %r9d
je 0xc909
cmpl $0x2, %r9d
je 0xc90e
movl %esi, %r9d
negl %r9d
cmovnsl %r9d, %esi
jmp 0xc90e
negl %esi
movslq %esi, %rsi
cmpl %ecx, %eax
jne 0xc98b
cmpq $0x1, %rdi
jne 0xc94f
cmpq $0x1, %r8
jne 0xc94f
movl 0x68(%r14), %ecx
cmpq $0x3, %rcx
ja 0xc7c3
leaq 0x8ded(%rip), %rdi      # 0x15720
movslq (%rdi,%rcx,4), %rcx
addq %rdi, %rcx
jmpq *%rcx
testq %rdx, %rdx
jle 0xc7c3
testq %rsi, %rsi
jg 0xc98b
jmp 0xc7c3
movl 0x4c(%r15), %eax
movl 0x4c(%rbx), %ecx
movl %ecx, 0x4c(%r15)
movl %eax, 0x4c(%rbx)
jmp 0xc7c3
cmpl $0x1, %eax
jne 0xc971
testq %rdx, %rdx
jle 0xc971
testq %rsi, %rsi
jg 0xc98b
testl %eax, %eax
jne 0xc7c3
testq %rdx, %rdx
jg 0xc7c3
testq %rsi, %rsi
jg 0xc7c3
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
movq %r12, %rcx
callq 0xbe0c
jmp 0xc7c3
nop