// File: realuptime[P]PolyDetector/PolyDetector.cpp
// Function: PolyDetector::dissolveCollinear(PolyLine&, PolyLine&)
bool PolyDetector::dissolveCollinear(PolyLine &l1, PolyLine &l2)
{
    if (verbose)
        logoutf("Dissolving collinear neighbors %s and %s", l1.toString(*this).c_str(), l2.toString(*this).c_str());
    
    assert(&l1 != &l2);
    
    uint32_t *p1 = nullptr, *p2 = nullptr;
    if (l1.aIdx == l2.aIdx || l1.aIdx == l2.bIdx)
    {
        p1 = &l1.bIdx; // other point (B)
        p2 = l1.aIdx == l2.aIdx ? &l2.bIdx : &l2.aIdx; // aidx is common point. other point
    }
    else if (l1.bIdx == l2.aIdx || l1.bIdx == l2.bIdx)
    {
        p1 = &l1.aIdx; // other point (A)
        p2 = l1.bIdx == l2.aIdx ? &l2.bIdx : &l2.aIdx; // bidx is common point. other point
    }
    if (!p1 || !p2)
    {
        assert(p1 && p2);
        return false;
    }

#if 1
    auto search = findLine(*p1, *p2, false);
    if (search)
    {
        logoutf("A line %s origLine:#%u already exists with P%u P%u!", search->toString(*this).c_str(), search->origLine, *p1, *p2);
        //assert(false);
        
        l1.setIgnore(*this, "rmCollinear.l1 (dup)");
        l2.setIgnore(*this, "rmCollinear.l2 (dup)");
        
        return false;
    }
#endif

    PolyLine nl;
    nl.id = uint32_t(lines.size());
    nl.aIdx = *p1;
    nl.bIdx = *p2;
    nl.a = intersectionPoints[nl.aIdx];
    nl.b = intersectionPoints[nl.bIdx];
    nl.calcCenter(); // calls CalculateFirstAndLastPoint
    nl.origLine = l1.origLine; // will be used to construct collinearLineMap
    nl.lastDissolveStep = l1.lastDissolveStep;
    nl.attr0 = l1.attr0;
    
    // build point to lines link
    addPointToLine(nl.aIdx, nl.id);
    addPointToLine(nl.bIdx, nl.id);
    
    // build neighbors
    for (auto &id : {l1.id, l2.id})
    {
        for (auto &n : _neighbors[id])
        {
            if (n != l1.id && n != l2.id)
            {
                auto l = findLine(n);
                if (l)
                {
                    _neighbors[nl.id].push_back(n);
                    _neighbors[n].push_back(nl.id);
                }
            }
        }
    }
    
    // set proper collinearities
    for (auto &kv : collinearLineMap)
    {
        if (kv.first == l1.id || kv.first == l2.id)
        {
            for (auto &c : kv.second)
                setCollinear(nl.id, c);
        }
    }
    
    // after neigh built!
    if (verbose)
        logoutf("ignore line %u and line %u", l1.id, l2.id);
    l1.setIgnore(*this, "rmCollinear.l1");
    l2.setIgnore(*this, "rmCollinear.l2");
    
    //return false; // test
    
    lineIdToIdx[nl.id] = uint32_t(lines.size());
    lines.push_back(nl);
    lines.back().sortNeigh(*this);
    if (verbose)
        logoutf("added new line %s by merging %u and %u", lines.back().toString(*this).c_str(), l1.id, l2.id);
    
    // it can be removed
    //dissolveCollinearLine(lines.back());
    
    return true;
}

// Assembly:
subq $0x278, %rsp            # imm = 0x278
movq %rdi, 0x268(%rsp)
movq %rsi, 0x260(%rsp)
movq %rdx, 0x258(%rsp)
movq 0x268(%rsp), %rax
movq %rax, 0x78(%rsp)
cmpl $0x0, 0x60(%rax)
je 0xbe3a
movq 0x78(%rsp), %rdx
movq 0x260(%rsp), %rsi
leaq 0x238(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x65a0
movq 0x68(%rsp), %rdi
callq 0x20b0
movq 0x78(%rsp), %rdx
movq %rax, 0x70(%rsp)
movq 0x258(%rsp), %rsi
leaq 0x218(%rsp), %rdi
callq 0x65a0
jmp 0xbdb0
leaq 0x218(%rsp), %rdi
callq 0x20b0
movq 0x70(%rsp), %rsi
movq %rax, %rdx
leaq 0x1aeaf(%rip), %rdi     # 0x26c7b
xorl %eax, %eax
callq 0x2050
jmp 0xbdd5
leaq 0x218(%rsp), %rdi
callq 0x2100
leaq 0x238(%rsp), %rdi
callq 0x2100
jmp 0xbe3a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x210(%rsp)
movl %eax, 0x20c(%rsp)
jmp 0xbe28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x210(%rsp)
movl %eax, 0x20c(%rsp)
leaq 0x218(%rsp), %rdi
callq 0x2100
leaq 0x238(%rsp), %rdi
callq 0x2100
jmp 0xc799
movq 0x260(%rsp), %rax
cmpq 0x258(%rsp), %rax
je 0xbe4e
jmp 0xbe6d
leaq 0x1a73b(%rip), %rdi     # 0x26590
leaq 0x1a29c(%rip), %rsi     # 0x260f8
movl $0x956, %edx            # imm = 0x956
leaq 0x1ae3d(%rip), %rcx     # 0x26ca5
callq 0x2120
movq $0x0, 0x200(%rsp)
movq $0x0, 0x1f8(%rsp)
movq 0x260(%rsp), %rax
movl 0x80(%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x80(%rcx), %eax
je 0xbec1
movq 0x260(%rsp), %rax
movl 0x80(%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x84(%rcx), %eax
jne 0xbf2f
movq 0x260(%rsp), %rax
addq $0x84, %rax
movq %rax, 0x200(%rsp)
movq 0x260(%rsp), %rax
movl 0x80(%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x80(%rcx), %eax
jne 0xbf0a
movq 0x258(%rsp), %rax
addq $0x84, %rax
movq %rax, 0x60(%rsp)
jmp 0xbf1d
movq 0x258(%rsp), %rax
addq $0x80, %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x1f8(%rsp)
jmp 0xbfd6
movq 0x260(%rsp), %rax
movl 0x84(%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x80(%rcx), %eax
je 0xbf6b
movq 0x260(%rsp), %rax
movl 0x84(%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x84(%rcx), %eax
jne 0xbfd4
movq 0x260(%rsp), %rax
addq $0x80, %rax
movq %rax, 0x200(%rsp)
movq 0x260(%rsp), %rax
movl 0x84(%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x80(%rcx), %eax
jne 0xbfb4
movq 0x258(%rsp), %rax
addq $0x84, %rax
movq %rax, 0x58(%rsp)
jmp 0xbfc7
movq 0x258(%rsp), %rax
addq $0x80, %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x1f8(%rsp)
jmp 0xbfd6
cmpq $0x0, 0x200(%rsp)
je 0xbfec
cmpq $0x0, 0x1f8(%rsp)
jne 0xc045
xorl %eax, %eax
cmpq $0x0, 0x200(%rsp)
movb %al, 0x57(%rsp)
je 0xc00d
cmpq $0x0, 0x1f8(%rsp)
setne %al
movb %al, 0x57(%rsp)
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0xc017
jmp 0xc019
jmp 0xc038
leaq 0x1acc2(%rip), %rdi     # 0x26ce2
leaq 0x1a0d1(%rip), %rsi     # 0x260f8
movl $0x965, %edx            # imm = 0x965
leaq 0x1ac72(%rip), %rcx     # 0x26ca5
callq 0x2120
movb $0x0, 0x277(%rsp)
jmp 0xc788
movq 0x78(%rsp), %rdi
movq 0x200(%rsp), %rax
movl (%rax), %esi
movq 0x1f8(%rsp), %rax
movl (%rax), %edx
xorl %ecx, %ecx
callq 0x9c50
movq %rax, 0x1f0(%rsp)
cmpq $0x0, 0x1f0(%rsp)
je 0xc14a
movq 0x78(%rsp), %rdx
movq 0x1f0(%rsp), %rsi
leaq 0x1d0(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x65a0
movq 0x48(%rsp), %rdi
callq 0x20b0
movq %rax, %rsi
movq 0x1f0(%rsp), %rax
movl 0x6c(%rax), %edx
movq 0x200(%rsp), %rax
movl (%rax), %ecx
movq 0x1f8(%rsp), %rax
movl (%rax), %r8d
leaq 0x1ac1c(%rip), %rdi     # 0x26ceb
xorl %eax, %eax
callq 0x2050
jmp 0xc0d8
leaq 0x1d0(%rsp), %rdi
callq 0x2100
movq 0x78(%rsp), %rsi
movq 0x260(%rsp), %rdi
leaq 0x1ac27(%rip), %rdx     # 0x26d20
callq 0xc7b0
movq 0x78(%rsp), %rsi
movq 0x258(%rsp), %rdi
leaq 0x1ac23(%rip), %rdx     # 0x26d35
callq 0xc7b0
movb $0x0, 0x277(%rsp)
jmp 0xc788
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x210(%rsp)
movl %eax, 0x20c(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0x2100
jmp 0xc799
leaq 0x140(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x12910
movq 0x78(%rsp), %rdi
addq $0x30, %rdi
callq 0x12b40
movq 0x78(%rsp), %rdi
movl %eax, 0x1a0(%rsp)
movq 0x200(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x1c0(%rsp)
movq 0x1f8(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x1c4(%rsp)
addq $0xc8, %rdi
movq %rdi, 0x38(%rsp)
movl 0x1c0(%rsp), %eax
movl %eax, %esi
callq 0x12a20
movq 0x38(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x140(%rsp)
movl 0x1c4(%rsp), %eax
movl %eax, %esi
callq 0x12a20
movq 0x40(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x148(%rsp)
callq 0x2fb0
jmp 0xc1e7
movq 0x78(%rsp), %rdi
movq 0x260(%rsp), %rax
movl 0x6c(%rax), %eax
movl %eax, 0x1ac(%rsp)
movq 0x260(%rsp), %rax
movl 0x88(%rax), %eax
movl %eax, 0x1c8(%rsp)
movq 0x260(%rsp), %rax
movl 0x70(%rax), %eax
movl %eax, 0x1b0(%rsp)
movl 0x1a0(%rsp), %edx
movl 0x1c0(%rsp), %esi
callq 0x6b50
jmp 0xc23a
movq 0x78(%rsp), %rdi
movl 0x1a0(%rsp), %edx
movl 0x1c4(%rsp), %esi
callq 0x6b50
jmp 0xc254
movq 0x260(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, 0x120(%rsp)
movq 0x258(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, 0x124(%rsp)
leaq 0x120(%rsp), %rax
movq %rax, 0x128(%rsp)
movq $0x2, 0x130(%rsp)
leaq 0x128(%rsp), %rax
movq %rax, 0x138(%rsp)
movq 0x138(%rsp), %rdi
callq 0x13b00
movq %rax, 0x118(%rsp)
movq 0x138(%rsp), %rdi
callq 0x13b10
movq %rax, 0x110(%rsp)
movq 0x118(%rsp), %rax
cmpq 0x110(%rsp), %rax
je 0xc497
movq 0x78(%rsp), %rdi
movq 0x118(%rsp), %rax
movq %rax, 0x108(%rsp)
addq $0x68, %rdi
movq 0x108(%rsp), %rsi
callq 0x12dd0
movq %rax, 0x30(%rsp)
jmp 0xc311
movq 0x30(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x100(%rsp), %rdi
callq 0x128b0
movq %rax, 0xf8(%rsp)
movq 0x100(%rsp), %rdi
callq 0x128e0
movq %rax, 0xf0(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x134e0
testb $0x1, %al
jne 0xc366
jmp 0xc47c
leaq 0xf8(%rsp), %rdi
callq 0x13520
movq %rax, 0xe8(%rsp)
movq 0xe8(%rsp), %rax
movl (%rax), %eax
movq 0x260(%rsp), %rcx
cmpl 0x60(%rcx), %eax
je 0xc468
movq 0xe8(%rsp), %rax
movl (%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x60(%rcx), %eax
je 0xc468
movq 0x78(%rsp), %rdi
movq 0xe8(%rsp), %rax
movl (%rax), %esi
movl $0x1, %edx
callq 0x7240
movq %rax, 0x28(%rsp)
jmp 0xc3d1
movq 0x28(%rsp), %rax
movq %rax, 0xe0(%rsp)
cmpq $0x0, 0xe0(%rsp)
je 0xc466
movq 0x78(%rsp), %rdi
addq $0x68, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x12dd0
movq %rax, 0x20(%rsp)
jmp 0xc406
movq 0x20(%rsp), %rdi
movq 0xe8(%rsp), %rsi
callq 0x12f60
jmp 0xc41a
movq 0x78(%rsp), %rdi
addq $0x68, %rdi
movq 0xe8(%rsp), %rsi
callq 0x12dd0
movq %rax, 0x18(%rsp)
jmp 0xc437
movq 0x18(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x12f60
jmp 0xc44b
jmp 0xc466
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x210(%rsp)
movl %eax, 0x20c(%rsp)
jmp 0xc779
jmp 0xc468
jmp 0xc46a
leaq 0xf8(%rsp), %rdi
callq 0x13530
jmp 0xc348
jmp 0xc47e
movq 0x118(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x118(%rsp)
jmp 0xc2ce
movq 0x78(%rsp), %rax
addq $0x98, %rax
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x14890
movq %rax, 0xd0(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x13ab0
movq %rax, 0xc8(%rsp)
leaq 0xd0(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x148c0
testb $0x1, %al
jne 0xc4f2
jmp 0xc5eb
leaq 0xd0(%rsp), %rdi
callq 0x148e0
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
movl (%rax), %eax
movq 0x260(%rsp), %rcx
cmpl 0x60(%rcx), %eax
je 0xc539
movq 0xc0(%rsp), %rax
movl (%rax), %eax
movq 0x258(%rsp), %rcx
cmpl 0x60(%rcx), %eax
jne 0xc5d7
movq 0xc0(%rsp), %rax
addq $0x8, %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x128b0
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x128e0
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x134e0
testb $0x1, %al
jne 0xc592
jmp 0xc5d5
leaq 0xb0(%rsp), %rdi
callq 0x13520
movq 0x78(%rsp), %rdi
movq %rax, 0xa0(%rsp)
movl 0x1a0(%rsp), %esi
movq 0xa0(%rsp), %rax
movl (%rax), %edx
callq 0xb670
jmp 0xc5c4
jmp 0xc5c6
leaq 0xb0(%rsp), %rdi
callq 0x13530
jmp 0xc577
jmp 0xc5d7
jmp 0xc5d9
leaq 0xd0(%rsp), %rdi
callq 0x14900
jmp 0xc4d4
movq 0x78(%rsp), %rax
cmpl $0x0, 0x60(%rax)
je 0xc61e
movq 0x260(%rsp), %rax
movl 0x60(%rax), %esi
movq 0x258(%rsp), %rax
movl 0x60(%rax), %edx
leaq 0x1a737(%rip), %rdi     # 0x26d4a
xorl %eax, %eax
callq 0x2050
jmp 0xc61c
jmp 0xc61e
movq 0x78(%rsp), %rsi
movq 0x260(%rsp), %rdi
leaq 0x1a734(%rip), %rdx     # 0x26d66
callq 0xc7b0
jmp 0xc639
movq 0x78(%rsp), %rsi
movq 0x258(%rsp), %rdi
leaq 0x1a728(%rip), %rdx     # 0x26d75
callq 0xc7b0
jmp 0xc654
movq 0x78(%rsp), %rdi
addq $0x30, %rdi
callq 0x12b40
movq 0x78(%rsp), %rdi
movl %eax, 0xc(%rsp)
addq $0x110, %rdi            # imm = 0x110
leaq 0x1a0(%rsp), %rsi
callq 0x14860
movq %rax, 0x10(%rsp)
jmp 0xc686
movq 0x78(%rsp), %rdi
movq 0x10(%rsp), %rax
movl 0xc(%rsp), %ecx
movl %ecx, (%rax)
addq $0x30, %rdi
leaq 0x140(%rsp), %rsi
callq 0x14050
jmp 0xc6a9
movq 0x78(%rsp), %rdi
addq $0x30, %rdi
callq 0x14e30
movq 0x78(%rsp), %rsi
movq %rax, %rdi
callq 0xb560
jmp 0xc6c6
movq 0x78(%rsp), %rax
cmpl $0x0, 0x60(%rax)
je 0xc762
movq 0x78(%rsp), %rdi
addq $0x30, %rdi
callq 0x14e30
movq 0x78(%rsp), %rdx
movq %rax, %rsi
leaq 0x80(%rsp), %rdi
callq 0x65a0
jmp 0xc6fa
leaq 0x80(%rsp), %rdi
callq 0x20b0
movq %rax, %rsi
movq 0x260(%rsp), %rax
movl 0x60(%rax), %edx
movq 0x258(%rsp), %rax
movl 0x60(%rax), %ecx
leaq 0x1a65d(%rip), %rdi     # 0x26d84
xorl %eax, %eax
callq 0x2050
jmp 0xc730
leaq 0x80(%rsp), %rdi
callq 0x2100
jmp 0xc762
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x210(%rsp)
movl %eax, 0x20c(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x2100
jmp 0xc779
movb $0x1, 0x277(%rsp)
leaq 0x140(%rsp), %rdi
callq 0x12a40
jmp 0xc788
leaq 0x140(%rsp), %rdi
callq 0x12a40
jmp 0xc799
movb 0x277(%rsp), %al
andb $0x1, %al
addq $0x278, %rsp            # imm = 0x278
retq
movq 0x210(%rsp), %rdi
callq 0x2280
nopw %cs:(%rax,%rax)