// File: /workspace/github_cpp_makefile_star2_O1/eliebe-5[P]Catmull-clark-subdivision/halfedge.cc
// Function: Mesh::subdivide()
void Mesh::subdivide()
{

    vertPool.pre_allocate_elements(fCount*3);
    edgePool.pre_allocate_elements(fCount*12);
    facePool.pre_allocate_elements(fCount*3);
    
    for(int i = 0; i < fCount; i++)
    {
        facePoint(facePool[i]);
    }

    v3 *vertL = new v3[vCount];
    
    for(int i = 0; i < vCount; i++)
    {
        vertL[i] = newVertex(vertPool[i]);
    }

    
    
    for(int i = 0; i < fCount; i++)
    {
        
        HEVert *fb = facePoint(facePool[i]);

        HEFace *f1 = facePool[i];
        HEFace *f2 = facePool.new_element();
        HEFace *f3 = facePool.new_element();
        HEFace *f4 = facePool.new_element();

        if(i != fCount - 1)
            splitEdges(facePool[i]->edge);

        HEEdge *e11 = facePool[i]->edge->next;
        HEEdge *e12 = e11->next;

        HEEdge *e13 = edgePool.new_element();
        HEEdge *e14 = edgePool.new_element();
        
        f1->edge = e11;

        e13->next = e14;
        e14->next = e11;

        e11->face = f1;
        e12->face = f1;
        e13->face = f1;
        e14->face = f1;
        
        e13->vert = e12->next->vert;
        e14->vert = fb;

        e11->vert->edge = e11;
        e12->vert->edge = e12;
        e13->vert->edge = e13;
        e14->vert->edge = e14;

        HEEdge *e21 = e12->next;
        HEEdge *e22 = e21->next;

        HEEdge *e23 = edgePool.new_element();
        HEEdge *e24 = edgePool.new_element();

        e24->pair = e13;
        e13->pair = e24;
        
        f2->edge = e21;

        e23->next = e24;
        e24->next = e21;

        e21->face = f2;
        e22->face = f2;
        e23->face = f2;
        e24->face = f2;
        
        e23->vert = e22->next->vert;
        e24->vert = fb;
        
        e21->vert->edge = e21;
        e22->vert->edge = e22;
        e23->vert->edge = e23;
        e24->vert->edge = e24;

        HEEdge *e31 = e22->next;
        HEEdge *e32 = e31->next;
        
        HEEdge *e33 = edgePool.new_element();
        HEEdge *e34 = edgePool.new_element();
        
        e34->pair = e23;
        e23->pair = e34;
        
        f3->edge = e31;

        e33->next = e34;
        e34->next = e31;
        
        e31->face = f3;
        e32->face = f3;
        e33->face = f3;
        e34->face = f3;

        e33->vert = e32->next->vert;
        e34->vert = fb;

        e31->vert->edge = e31;
        e32->vert->edge = e32;
        e33->vert->edge = e33;
        e34->vert->edge = e34;
        
        HEEdge *e41 = e32->next;
        HEEdge *e42 = e41->next;
        
        HEEdge *e43 = edgePool.new_element();
        HEEdge *e44 = edgePool.new_element();
        
        e43->pair = e14;
        e14->pair = e43;

        e44->pair = e33;
        e33->pair = e44;
        
        f4->edge = e41;

        e43->next = e44;
        e44->next = e41;

        e41->face = f4;
        e42->face = f4;
        e43->face = f4;
        e44->face = f4;
        
        e43->vert = e42->next->vert;
        e44->vert = fb;

        e41->vert->edge = e41;
        e42->vert->edge = e42;
        e43->vert->edge = e43;
        e44->vert->edge = e44;

        
        v2 fuv;

        fuv = (e12->uv + e22->uv + e32->uv + e42->uv) * 0.25;
        
        e13->uv = e12->next->uv;
        e23->uv = e22->next->uv;
        e33->uv = e32->next->uv;
        e43->uv = e42->next->uv;
        
        e14->uv = fuv;
        e24->uv = fuv;
        e34->uv = fuv;
        e44->uv = fuv;
        
        e12->next = e13;
        e22->next = e23;
        e32->next = e33;
        e42->next = e43;

        e12->split = false;
        e22->split = false;
        e32->split = false;
        e42->split = false;

        e11->split = false;
        e21->split = false;
        e31->split = false;
        e41->split = false;

        v3 normal1 = (e14->vert->pos - e11->vert->pos) * (e14->vert->pos - e13->vert->pos);
        v3 normal2 = (e24->vert->pos - e21->vert->pos) * (e24->vert->pos - e23->vert->pos);
        v3 normal3 = (e34->vert->pos - e31->vert->pos) * (e34->vert->pos - e33->vert->pos);
        v3 normal4 = (e44->vert->pos - e41->vert->pos) * (e44->vert->pos - e43->vert->pos);

        float l1 = sqrt(normal1.x + normal1.y + normal1.z);
        normal1 = normal1 / l1;
        float l2 = sqrt(normal2.x + normal2.y + normal2.z);
        normal2 = normal2 / l2;
        float l3 = sqrt(normal3.x + normal3.y + normal3.z);
        normal3 = normal3 / l3;
        float l4 = sqrt(normal4.x + normal4.y + normal4.z);
        normal4 = normal4 / l4;

        e11->norm = normal1;
        e12->norm = normal1;
        e13->norm = normal1;
        e14->norm = normal1;

        e21->norm = normal2;
        e22->norm = normal2;
        e23->norm = normal2;
        e24->norm = normal2;
        
        e31->norm = normal3;
        e32->norm = normal3;
        e33->norm = normal3;
        e34->norm = normal3;
        
        e41->norm = normal4;
        e42->norm = normal4;
        e43->norm = normal4;
        e44->norm = normal4;
        
        facePool[i]->avg = nullptr;
    }

    for(int i = 0; i < vCount; i++)
    {
        vertPool[i]->pos = vertL[i];
    }

    delete[] vertL;
    
    vCount = vCount + fCount*3;
    fCount = fCount * eStep;
    
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movl 0x3c(%rdi), %eax
movl 0x60(%rdi), %ecx
leal (%rcx,%rcx,2), %ecx
leal (%rax,%rcx), %ebp
decl %ebp
shrl $0x9, %ebp
cmpl 0x38(%rdi), %ebp
jb 0x40f6
leaq 0x20(%rbx), %r14
movq %rsp, %r15
movl $0x4000, %edi           # imm = 0x4000
callq 0x2030
xorps %xmm0, %xmm0
movl $0x10, %ecx
movups %xmm0, (%rax,%rcx)
addq $0x20, %rcx
cmpq $0x4010, %rcx           # imm = 0x4010
jne 0x40b6
movq %rax, (%rsp)
movq 0x28(%rbx), %rsi
cmpq 0x30(%rbx), %rsi
je 0x40df
movq %rax, (%rsi)
addq $0x8, 0x28(%rbx)
jmp 0x40ea
movq %r14, %rdi
movq %r15, %rdx
callq 0x5120
movl 0x38(%rbx), %eax
incl %eax
movl %eax, 0x38(%rbx)
cmpl %eax, %ebp
jae 0x40a4
movl 0x1c(%rbx), %eax
movl 0x60(%rbx), %ecx
leal (%rcx,%rcx,2), %ecx
leal (%rax,%rcx,4), %ebp
decl %ebp
shrl $0x8, %ebp
cmpl 0x18(%rbx), %ebp
jb 0x4171
movq %rsp, %r14
movl $0x4000, %edi           # imm = 0x4000
callq 0x2030
xorps %xmm0, %xmm0
xorl %ecx, %ecx
movb $0x0, 0x3c(%rax,%rcx)
movups %xmm0, (%rax,%rcx)
movups %xmm0, 0x10(%rax,%rcx)
movq $0x0, 0x20(%rax,%rcx)
addq $0x40, %rcx
cmpq $0x4000, %rcx           # imm = 0x4000
jne 0x411e
movq %rax, (%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x415a
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x4165
movq %rbx, %rdi
movq %r14, %rdx
callq 0x538c
movl 0x18(%rbx), %eax
incl %eax
movl %eax, 0x18(%rbx)
cmpl %eax, %ebp
jae 0x410f
leaq 0x40(%rbx), %r14
movl 0x5c(%rbx), %eax
movl 0x60(%rbx), %ecx
leal (%rcx,%rcx,2), %ecx
leal (%rax,%rcx), %ebp
decl %ebp
shrl $0xa, %ebp
cmpl 0x58(%rbx), %ebp
jb 0x41d9
movq %rsp, %r15
movl $0x4000, %edi           # imm = 0x4000
callq 0x2030
movq %rax, %r12
movl $0x4000, %edx           # imm = 0x4000
movq %rax, %rdi
xorl %esi, %esi
callq 0x2110
movq %r12, (%rsp)
movq 0x48(%rbx), %rsi
cmpq 0x50(%rbx), %rsi
je 0x41c2
movq %r12, (%rsi)
addq $0x8, 0x48(%rbx)
jmp 0x41cd
movq %r14, %rdi
movq %r15, %rdx
callq 0x5256
movl 0x58(%rbx), %eax
incl %eax
movl %eax, 0x58(%rbx)
cmpl %eax, %ebp
jae 0x418e
cmpl $0x0, 0x60(%rbx)
jle 0x4211
xorl %ebp, %ebp
cmpl %ebp, 0x5c(%rbx)
jbe 0x430d
movl %ebp, %esi
andl $0x3ff, %esi            # imm = 0x3FF
movq 0x40(%rbx), %rax
movl %ebp, %ecx
shrl $0xa, %ecx
shll $0x4, %esi
addq (%rax,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x3ba4
incl %ebp
cmpl 0x60(%rbx), %ebp
jl 0x41e1
movslq 0x68(%rbx), %rax
movl $0xc, %ecx
mulq %rcx
movq $-0x1, %rdi
cmovnoq %rax, %rdi
callq 0x2030
movq %rax, %r15
cmpl $0x0, 0x68(%rbx)
jle 0x428f
xorl %r13d, %r13d
movq %rsp, %r12
movq %r15, %rbp
movl 0x3c(%rbx), %eax
cmpq %rax, %r13
jae 0x432b
movl %r13d, %edx
andl $0x1ff, %edx            # imm = 0x1FF
movq 0x20(%rbx), %rax
movl %r13d, %ecx
shrl $0x9, %ecx
shll $0x5, %edx
addq (%rax,%rcx,8), %rdx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3ec2
movl 0x8(%rsp), %eax
movl %eax, 0x8(%rbp)
movq (%rsp), %rax
movq %rax, (%rbp)
incq %r13
movslq 0x68(%rbx), %rax
addq $0xc, %rbp
cmpq %rax, %r13
jl 0x423f
cmpl $0x0, 0x60(%rbx)
jg 0x437b
cmpl $0x0, 0x68(%rbx)
jle 0x42e6
xorl %eax, %eax
movq %r15, %rcx
movl 0x3c(%rbx), %edx
cmpq %rdx, %rax
jae 0x4349
movl %eax, %edx
andl $0x1ff, %edx            # imm = 0x1FF
movq 0x20(%rbx), %rsi
movl %eax, %edi
shrl $0x9, %edi
movq (%rsi,%rdi,8), %rsi
shll $0x5, %edx
movl 0x8(%rcx), %edi
movl %edi, 0x8(%rsi,%rdx)
movq (%rcx), %rdi
movq %rdi, (%rsi,%rdx)
incq %rax
movslq 0x68(%rbx), %rdx
addq $0xc, %rcx
cmpq %rdx, %rax
jl 0x42a4
movq %r15, %rdi
callq 0x21c0
movl 0x60(%rbx), %eax
leal (%rax,%rax,2), %ecx
addl %ecx, 0x68(%rbx)
imull 0x64(%rbx), %eax
movl %eax, 0x60(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1dfd(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
jmp 0x4365
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1ddf(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
jmp 0x4365
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1dc1(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
movq 0x4c6c(%rip), %rsi      # 0x8fd8
movq 0x4c5d(%rip), %rdx      # 0x8fd0
movq %rbx, %rdi
callq 0x2280
cmpl $0x0, 0x5c(%rbx)
jne 0x439f
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1d89(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
jmp 0x4365
movq 0x40(%rbx), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x3ba4
cmpl $0x0, 0x5c(%rbx)
jne 0x43d2
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1d56(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
jmp 0x4365
movq %rax, %r15
movq 0x40(%rbx), %rax
movq (%rax), %rbp
movq %r14, %rdi
callq 0x49f6
movq %rax, %r13
movq %r14, %rdi
callq 0x49f6
movq %rax, %r12
movq %r14, %rdi
callq 0x49f6
cmpl $0x1, 0x60(%rbx)
je 0x4439
cmpl $0x0, 0x5c(%rbx)
jne 0x4427
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1d04(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
jmp 0x4365
movq 0x40(%rbx), %rax
movq (%rax), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x3e80
cmpl $0x0, 0x5c(%rbx)
jne 0x4460
movl $0x10, %edi
callq 0x20f0
movq %rax, %rbx
leaq 0x1ccb(%rip), %rsi      # 0x611e
movq %rax, %rdi
callq 0x2070
jmp 0x4365
movq 0x40(%rbx), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x18(%rax), %r14
movq 0x18(%r14), %rax
movq %rax, 0x10(%rsp)
movq %rbx, %rdi
callq 0x4ab8
movq %rax, 0x18(%rsp)
movq %rbx, %rdi
callq 0x4ab8
movq %r14, (%rbp)
movq 0x18(%rsp), %rdx
movq %rax, 0x18(%rdx)
movq %r14, 0x18(%rax)
movq %rbp, 0x10(%r14)
movq 0x10(%rsp), %rsi
movq %rbp, 0x10(%rsi)
movq %rbp, 0x10(%rdx)
movq %rbp, 0x10(%rax)
movq 0x18(%rsi), %rbp
movq (%rbp), %rcx
movq %rcx, (%rdx)
movq %r15, (%rax)
movq (%r14), %rcx
movq %r14, 0x10(%rcx)
movq (%rsi), %rcx
movq %rsi, 0x10(%rcx)
movq (%rdx), %rcx
movq %rdx, 0x10(%rcx)
movq %rdx, %r14
movq %rax, 0x10(%r15)
movq 0x18(%rbp), %rax
movq %rax, 0x20(%rsp)
movq %rbx, %rdi
callq 0x4ab8
movq %rax, 0x10(%rsp)
movq %rbx, %rdi
callq 0x4ab8
movq %r14, 0x8(%rax)
movq %rax, 0x8(%r14)
movq %rbp, (%r13)
movq 0x10(%rsp), %rdx
movq %rax, 0x18(%rdx)
movq %rbp, 0x18(%rax)
movq %r13, 0x10(%rbp)
movq 0x20(%rsp), %rsi
movq %r13, 0x10(%rsi)
movq %r13, 0x10(%rdx)
movq %r13, 0x10(%rax)
movq 0x18(%rsi), %r14
movq (%r14), %rcx
movq %rcx, (%rdx)
movq %r15, (%rax)
movq (%rbp), %rcx
movq %rbp, 0x10(%rcx)
movq (%rsi), %rcx
movq %rsi, 0x10(%rcx)
movq (%rdx), %rcx
movq %rdx, 0x10(%rcx)
movq %rax, 0x10(%r15)
movq 0x18(%r14), %rbp
movq %rbx, %rdi
callq 0x4ab8
movq %rax, %r13
movq %rbx, %rdi
callq 0x4ab8
movq 0x10(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq %rax, 0x8(%rcx)
movq %r14, (%r12)
movq %rax, 0x18(%r13)
movq %r14, 0x18(%rax)
movq %r12, 0x10(%r14)
movq %r12, 0x10(%rbp)
movq %r12, 0x10(%r13)
movq %r12, 0x10(%rax)
movq 0x18(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, (%r13)
movq %r15, (%rax)
movq (%r14), %rcx
movq %r14, 0x10(%rcx)
movq (%rbp), %rcx
movq %rbp, 0x10(%rcx)
movq (%r13), %rcx
movq %r13, 0x10(%rcx)
movq %rax, 0x10(%r15)
movq %rbx, %rdi
callq 0x4ab8
movq %rbx, %rdi
callq 0x4ab8
jmp 0x45d4
jmp 0x45d4
jmp 0x45d4
jmp 0x45d4
jmp 0x45d4
jmp 0x45d4
movq %rax, %r14
movq %rbx, %rdi
callq 0x2140
movq %r14, %rdi
callq 0x2290
nop