// File: /workspace/github_cpp_makefile_star2_O2/hzeller[P]gcode-multi-shell-extrude/third_party/clipper.cpp
// Function: ClipperLib::Clipper::JoinCommonEdges()
void Clipper::JoinCommonEdges()
{
  for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
  {
    Join* join = m_Joins[i];

    OutRec *outRec1 = GetOutRec(join->OutPt1->Idx);
    OutRec *outRec2 = GetOutRec(join->OutPt2->Idx);

    if (!outRec1->Pts || !outRec2->Pts) continue;

    //get the polygon fragment with the correct hole state (FirstLeft)
    //before calling JoinPoints() ...
    OutRec *holeStateRec;
    if (outRec1 == outRec2) holeStateRec = outRec1;
    else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2;
    else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1;
    else holeStateRec = GetLowermostRec(outRec1, outRec2);

    if (!JoinPoints(join, outRec1, outRec2)) continue;

    if (outRec1 == outRec2)
    {
      //instead of joining two polygons, we've just created a new one by
      //splitting one polygon into two.
      outRec1->Pts = join->OutPt1;
      outRec1->BottomPt = 0;
      outRec2 = CreateOutRec();
      outRec2->Pts = join->OutPt2;

      //update all OutRec2.Pts Idx's ...
      UpdateOutPtIdxs(*outRec2);

      //We now need to check every OutRec.FirstLeft pointer. If it points
      //to OutRec1 it may need to point to OutRec2 instead ...
      if (m_UsingPolyTree)
        for (PolyOutList::size_type j = 0; j < m_PolyOuts.size() - 1; j++)
        {
          OutRec* oRec = m_PolyOuts[j];
          if (!oRec->Pts || ParseFirstLeft(oRec->FirstLeft) != outRec1 ||
            oRec->IsHole == outRec1->IsHole) continue;
          if (Poly2ContainsPoly1(oRec->Pts, join->OutPt2))
            oRec->FirstLeft = outRec2;
        }

      if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
      {
        //outRec2 is contained by outRec1 ...
        outRec2->IsHole = !outRec1->IsHole;
        outRec2->FirstLeft = outRec1;

        //fixup FirstLeft pointers that may need reassigning to OutRec1
        if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);

        if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0))
          ReversePolyPtLinks(outRec2->Pts);
            
      } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
      {
        //outRec1 is contained by outRec2 ...
        outRec2->IsHole = outRec1->IsHole;
        outRec1->IsHole = !outRec2->IsHole;
        outRec2->FirstLeft = outRec1->FirstLeft;
        outRec1->FirstLeft = outRec2;

        //fixup FirstLeft pointers that may need reassigning to OutRec1
        if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2);

        if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
          ReversePolyPtLinks(outRec1->Pts);
      } 
      else
      {
        //the 2 polygons are completely separate ...
        outRec2->IsHole = outRec1->IsHole;
        outRec2->FirstLeft = outRec1->FirstLeft;

        //fixup FirstLeft pointers that may need reassigning to OutRec2
        if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2);
      }
     
    } else
    {
      //joined 2 polygons together ...

      outRec2->Pts = 0;
      outRec2->BottomPt = 0;
      outRec2->Idx = outRec1->Idx;

      outRec1->IsHole = holeStateRec->IsHole;
      if (holeStateRec == outRec2) 
        outRec1->FirstLeft = outRec2->FirstLeft;
      outRec2->FirstLeft = outRec1;

      //fixup FirstLeft pointers that may need reassigning to OutRec1
      if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
xorl %ebp, %ebp
movq 0x20(%rbx), %rax
movq 0x28(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rcx, %rbp
jae 0xa6be
movq (%rax,%rbp,8), %r15
movq (%r15), %rax
movl (%rax), %esi
movq %rbx, %rdi
callq 0xb718
movq %rax, %r14
movq 0x8(%r15), %rax
movl (%rax), %esi
movq %rbx, %rdi
callq 0xb718
cmpq $0x0, 0x18(%r14)
je 0xa6b6
movq %rax, %r12
cmpq $0x0, 0x18(%rax)
je 0xa6b6
movq %r14, %r13
cmpq %r12, %r14
je 0xa488
movq %r14, %rdi
movq %r12, %rsi
callq 0xb702
movq %r12, %r13
testb %al, %al
jne 0xa488
movq %r12, %rdi
movq %r14, %rsi
callq 0xb702
movq %r14, %r13
testb %al, %al
jne 0xa488
movq %r14, %rdi
movq %r12, %rsi
callq 0xb681
movq %rax, %r13
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %r12, %rcx
callq 0xc7dc
testb %al, %al
je 0xa6b6
cmpq %r12, %r14
je 0xa4f5
leaq 0x18(%r12), %rax
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movl (%r14), %eax
movl %eax, (%r12)
movb 0x4(%r13), %al
movb %al, 0x4(%r14)
cmpq %r12, %r13
jne 0xa4d0
movq 0x8(%r12), %rax
movq %rax, 0x8(%r14)
movq %r14, 0x8(%r12)
cmpb $0x1, 0xbd(%rbx)
jne 0xa6b6
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0xcd1e
jmp 0xa6b6
movq %rbp, 0x10(%rsp)
movq (%r15), %rax
movq %rax, 0x18(%r14)
andq $0x0, 0x20(%r14)
movq %rbx, %rdi
callq 0xb734
movq %rax, %rdi
movq 0x8(%r15), %rax
movq %rax, 0x18(%rdi)
movq %rdi, 0x18(%rsp)
callq 0xfa42
movb 0xbd(%rbx), %al
movb %al, 0xf(%rsp)
cmpb $0x1, %al
jne 0xa5a6
movq 0x8(%rbx), %rdx
movq 0x10(%rbx), %r12
subq %rdx, %r12
sarq $0x3, %r12
decq %r12
xorl %ebp, %ebp
movq %rdx, 0x20(%rsp)
cmpq %r12, %rbp
je 0xa5a6
movq (%rdx,%rbp,8), %rax
movq 0x18(%rax), %rdi
testq %rdi, %rdi
je 0xa5a1
leaq 0x8(%rax), %r13
movq %r13, %rcx
movq (%rcx), %rcx
testq %rcx, %rcx
je 0xa578
cmpq $0x0, 0x18(%rcx)
jne 0xa578
addq $0x8, %rcx
jmp 0xa563
cmpq %r14, %rcx
jne 0xa5a1
movb 0x4(%rax), %al
cmpb 0x4(%r14), %al
je 0xa5a1
movq 0x8(%r15), %rsi
callq 0x7eb3
movq 0x20(%rsp), %rdx
testb %al, %al
je 0xa5a1
movq 0x18(%rsp), %rax
movq %rax, (%r13)
incq %rbp
jmp 0xa54a
movq 0x18(%rsp), %r12
movq 0x18(%r12), %r15
movq 0x18(%r14), %r13
movq %r15, %rdi
movq %r13, %rsi
callq 0x7eb3
testb %al, %al
je 0xa61e
movb 0x4(%r14), %bpl
xorb $0x1, %bpl
movb %bpl, 0x4(%r12)
movq %r14, 0x8(%r12)
cmpb $0x0, 0xf(%rsp)
je 0xa5ef
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0xcd1e
movb 0x4(%r12), %bpl
xorb 0xbc(%rbx), %bpl
movq %r12, %rdi
callq 0x7c11
ucomisd 0x90ca(%rip), %xmm0     # 0x136d0
seta %al
cmpb %al, %bpl
movq 0x10(%rsp), %rbp
jne 0xa6b6
movq 0x18(%r12), %rdi
jmp 0xa68c
movq %r13, %rdi
movq %r15, %rsi
callq 0x7eb3
movb 0x4(%r14), %bpl
movb %bpl, 0x4(%r12)
testb %al, %al
je 0xa693
xorb $0x1, %bpl
movb %bpl, 0x4(%r14)
movq 0x8(%r14), %rax
movq %rax, 0x8(%r12)
movq %r12, 0x8(%r14)
cmpb $0x0, 0xf(%rsp)
je 0xa664
movq %rbx, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0xcd1e
movb 0x4(%r14), %bpl
xorb 0xbc(%rbx), %bpl
movq %r14, %rdi
callq 0x7c11
ucomisd 0x9055(%rip), %xmm0     # 0x136d0
seta %al
cmpb %al, %bpl
movq 0x10(%rsp), %rbp
jne 0xa6b6
movq 0x18(%r14), %rdi
callq 0x8299
jmp 0xa6b6
movq 0x8(%r14), %rax
movq %rax, 0x8(%r12)
cmpb $0x0, 0xf(%rsp)
movq 0x10(%rsp), %rbp
je 0xa6b6
movq %rbx, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0xccbe
incq %rbp
jmp 0xa3fb
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop