// File: /workspace/github_cpp_makefile_star2_O1/MarkCBell[P]twister/./twister/kernel/twister.cpp
// Function: rectangle::half_twist(Sign)
void rectangle::half_twist(Sign whichway)
{
	output_debugging("half-twist", 2);
	
	// Let's remember some frequently used information.
	manifold *M = sq[0]->home;
	
	// First find out if we need a new layer.
	bool need_new_layer = false;
	for (int i = 0; i < length; i++)
		if (! sq[i]->get_status())
		{
			need_new_layer = true;
			break;
		}
	
	if ((M->marked_points[front] != standard) || (M->marked_points[back] != standard))
		need_new_layer = true;
	
	if (need_new_layer) M->insert_layer();
	
	drill();  // First drill a tunnel down the core of the rectangle.
	// Then attach a 2-handle in such a way as to perform a half-twist.
	
	for (int i = 0; i < length; i++)
		sq[i]->set_status(false);
	
	M->marked_points[front] = half_twisted;
	M->marked_points[back] = half_twisted;
	
	// We do this in 2 stages:
	// 1) Glue in a singular 2-handle.
	// 2) Thicken it to a regular 2-handle.
	
	// More frequently used information.
	int layer_number = M->get_num_layers();
	
	// Get some marker tetrahedra.
	tetra *first_marker = new tetra(M, marker);  // This will be our starting marker.
	tetra *mid_marker = new tetra(M, marker);  // This will be our midpoint marker.
	
	// Glue the marker in.
	first_marker->gluesym(sq[0]->get_tetra((upright[0]) ? 0 : 4)->get_child(), 3, (upright[0]) ? perm(1,3,0,2) : perm(1,3,0,2));
	
	if (one_ended)
	{
		mid_marker->gluesym(sq[0]->get_tetra((upright[0]) ? 2 : 5)->get_child()->get_child(), 3, (upright[0]) ? perm(0,1,3,2) : perm(0,1,3,2));
	}
	else
	{
		mid_marker->gluesym(sq[length-1]->get_tetra((upright[length-1]) ? 3 : 0)->get_child(), 3, (upright[length-1]) ? perm(0,3,2,1) : perm(3,1,2,0));
	}
	// ---===================================================---
	
	// Now begin working our way around, extending the singular 2-handle as we go.
	tetra *current = first_marker;  // Start at the first_marker.
	
	// Go through the tunnel for the first time (pre / post swirl as necessary).
	if (whichway == plus)  // Pre-swirl
		current = swirl(M, current, layer_number);  // See figure above convert_cube_to_gadget to see how this moves across the boundary faces.
	
	for (int c = 0; c < 2 * length + 2; c++)  // Work our way down the tunnel.
		current = tunnel_walk(M, current, layer_number);
	
	if (whichway == minus)  // Post-swirl
		current = swirl(M, current, layer_number);
	
	// Work our way around the 'far' boundary component until we get back to a marker.
	while (current != mid_marker)
		current = boundary_walk(M, current, layer_number);
	
	current->set_category(filler);  // Make our mid marker part of the singular 2-handle.
	
	// Go through the tunnel a second time (pre / post swirl as necessary).
	if ((whichway == minus) ^ (one_ended))  // Pre-swirl
		current = swirl(M, current, layer_number);
	
	for (int c = 0; c < 2 * length + 2; c++)  // Work our way through the tunnel again.
		current = tunnel_walk(M, current, layer_number);
	
	if ((whichway == plus) ^ (one_ended))  // Post-swirl
		current = swirl(M, current, layer_number);
	
	// Work our way around the 'near' boundary component until we hit our starting marker.
	while (current != first_marker)
		current = boundary_walk(M, current, layer_number);
	
	current->set_category(filler);  // Make our starting marker part of the singular 2-handle.
	// We've now gone all the way around once and added in a singular 2-handle.
	
	// We'd better go around again thickening the singular 2-handle into a regular one.
	// Note: Folding-off without thickening may produce a non-manifold.
	
	tetra *thicken_marker = new tetra(M, marker);  // This will be our thickening start point marker.
	// We glue thicken_marker down via its 3 face with 0 glued to the singularity of the 2-handle.
	// The edge of the 2-handle meeting the 1 & 2 vertices is 'top'.
	
	perm p = (current->get_gluedto(0) == NULL) ? perm(3,1,2,0) : ((current->get_gluedto(1) == NULL) ? perm(3,2,0,1) : perm(3,0,1,2));
	thicken_marker->gluesym(current, 3, p);
	current = thicken_marker;
	
	current->walk_about(1);
	while (current->get_gluedto(1) != thicken_marker) 
	{
		tetra *next_tetra = new tetra(M, filler);
		current->subbedby(next_tetra, 1, perm(0,3,1,2));
		current->walk_about(1);  // Re-close the faces.
		current = next_tetra;  // Move forwards
		current->walk_about(1);
	}
	
	current = current->get_gluedto(1);
	current->set_category(filler);
	
	// All done. Our singular 2-handle is now a regular one.
	
	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %esi, %ebp
movq %rdi, %r14
leaq 0x38(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x657e(%rip), %rsi      # 0x17685
leaq 0x6581(%rip), %rdx      # 0x1768f
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x86fe
movq %rbx, %rdi
movl $0x2, %esi
callq 0x4209
movq 0x28(%rsp), %rdi
cmpq %r15, %rdi
je 0x1113f
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3220
movq 0x8(%r14), %rax
movq (%rax), %rcx
movq 0x38(%rcx), %rbx
movslq (%r14), %rcx
testq %rcx, %rcx
setg %dl
jle 0x1117f
movq (%rax), %rsi
cmpb $0x1, 0x32(%rsi)
jne 0x1117f
movl $0x1, %esi
movq %rsi, %rdx
cmpq %rsi, %rcx
je 0x11179
movq (%rax,%rdx,8), %rdi
leaq 0x1(%rdx), %rsi
cmpb $0x0, 0x32(%rdi)
jne 0x11163
cmpq %rcx, %rdx
setb %dl
movslq 0x18(%r14), %rcx
movq 0x58(%rbx), %rax
cmpl $0x0, (%rax,%rcx,4)
jne 0x1119e
movslq 0x1c(%r14), %rcx
cmpl $0x0, (%rax,%rcx,4)
sete %al
notb %dl
testb %al, %dl
jne 0x111a6
movq %rbx, %rdi
callq 0x105e6
movq %r14, %rdi
callq 0x10ad0
movslq (%r14), %rax
testq %rax, %rax
jle 0x111cc
movq 0x8(%r14), %rcx
xorl %edx, %edx
movq (%rcx,%rdx,8), %rsi
movb $0x0, 0x32(%rsi)
incq %rdx
cmpq %rdx, %rax
jne 0x111bc
movslq 0x18(%r14), %rax
movq 0x58(%rbx), %rcx
movl $0x2, %edx
movl %edx, (%rcx,%rax,4)
movslq 0x1c(%r14), %rax
movl %edx, (%rcx,%rax,4)
movl 0x38(%rbx), %r12d
movl $0xc0, %edi
callq 0x3210
movq $0x0, (%rsp)
movq %rax, 0x10(%rsp)
movq %rax, %rdi
movq %rbx, %rsi
movl $0x8, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0xdc7c
movl %ebp, 0xc(%rsp)
movl $0xc0, %edi
callq 0x3210
movq %rax, %r13
movq $0x0, (%rsp)
movq %rax, %rdi
movq %rbx, %rsi
movl $0x8, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0xdc7c
movq 0x8(%r14), %rax
movq 0x10(%r14), %rcx
movq (%rax), %rax
movzbl (%rcx), %ecx
xorl $0x1, %ecx
shll $0x5, %ecx
movq (%rax,%rcx), %rax
movq 0x88(%rax), %r15
leaq 0x18(%rsp), %rbp
movq %rbp, %rdi
movl $0x1, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x8630
movq 0x10(%rsp), %rdi
movq %r15, %rsi
movl $0x3, %edx
movq %rbp, %rcx
callq 0xde78
movq 0x8(%r14), %rax
cmpb $0x1, 0x20(%r14)
jne 0x11319
movq 0x10(%r14), %rcx
cmpb $0x0, (%rcx)
movl $0x10, %ecx
movl $0x28, %edx
cmovneq %rcx, %rdx
movq (%rax), %rax
movq (%rax,%rdx), %rax
movq 0x88(%rax), %rax
movq 0x88(%rax), %r15
leaq 0x18(%rsp), %rbp
movq %rbp, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8630
movq %r13, %rdi
movq %r15, %rsi
movl $0x3, %edx
movq %rbp, %rcx
callq 0xde78
movl 0xc(%rsp), %ebp
jmp 0x11390
movslq (%r14), %rcx
movq 0x10(%r14), %rdx
xorl %esi, %esi
cmpb $0x0, -0x1(%rdx,%rcx)
movq -0x8(%rax,%rcx,8), %rax
movl $0x18, %edi
cmoveq %rsi, %rdi
movq (%rax,%rdi), %rax
movq 0x88(%rax), %r15
cmpb $0x1, -0x1(%rdx,%rcx)
movl 0xc(%rsp), %ebp
leaq 0x18(%rsp), %rdi
jne 0x11364
xorl %esi, %esi
movl $0x3, %edx
movl $0x2, %ecx
movl $0x1, %r8d
jmp 0x11376
movl $0x3, %esi
movl $0x1, %edx
movl $0x2, %ecx
xorl %r8d, %r8d
callq 0x8630
leaq 0x18(%rsp), %rcx
movq %r13, %rdi
movq %r15, %rsi
movl $0x3, %edx
callq 0xde78
cmpl $0x1, %ebp
jne 0x113aa
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
movl %r12d, %edx
callq 0x10d85
movq %rax, %r15
jmp 0x113af
movq 0x10(%rsp), %r15
cmpl $0x0, (%r14)
js 0x113d6
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10f12
movq %rax, %r15
movl (%r14), %eax
addl %eax, %eax
incl %ebp
cmpl %eax, %ebp
jle 0x113ba
movl 0xc(%rsp), %ebp
cmpl $-0x1, %ebp
jne 0x113f0
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10d85
movq %rax, %r15
cmpq %r13, %r15
je 0x1140b
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10ff4
movq %rax, %r15
cmpq %r13, %rax
jne 0x113f5
cmpl $-0x1, %ebp
sete %al
movl $0x7, 0x70(%r15)
cmpb %al, 0x20(%r14)
je 0x11430
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10d85
movq %rax, %r15
cmpl $0x0, (%r14)
js 0x11457
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10f12
movq %rax, %r15
movl (%r14), %eax
addl %eax, %eax
incl %ebp
cmpl %eax, %ebp
jle 0x1143b
cmpl $0x1, 0xc(%rsp)
sete %al
cmpb %al, 0x20(%r14)
je 0x11476
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10d85
movq %rax, %r15
movq 0x10(%rsp), %r14
cmpq %r14, %r15
je 0x11496
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x10ff4
movq %rax, %r15
cmpq %r14, %rax
jne 0x11480
movl $0x7, 0x70(%r15)
movl $0xc0, %edi
callq 0x3210
movq %rax, %r14
movq $0x0, (%rsp)
movq %rax, %rdi
movq %rbx, %rsi
movl $0x8, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0xdc7c
cmpq $0x0, 0x10(%r15)
je 0x114fb
cmpq $0x0, 0x18(%r15)
je 0x11514
leaq 0x18(%rsp), %rdi
movl $0x3, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x2, %r8d
jmp 0x1152b
leaq 0x18(%rsp), %rdi
movl $0x3, %esi
movl $0x1, %edx
movl $0x2, %ecx
xorl %r8d, %r8d
jmp 0x1152b
leaq 0x18(%rsp), %rdi
movl $0x3, %esi
movl $0x2, %edx
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0x8630
leaq 0x18(%rsp), %rcx
movq %r14, %rdi
movq %r15, %rsi
movl $0x3, %edx
callq 0xde78
movq %r14, %rdi
movl $0x1, %esi
callq 0xe150
movq 0x18(%r14), %rax
cmpq %r14, %rax
je 0x115f5
leaq 0x48(%rsp), %r15
movq %r14, %r13
movl $0xc0, %edi
callq 0x3210
movq %rax, %r12
movq $0x0, (%rsp)
movq %rax, %rdi
movq %rbx, %rsi
movl $0x7, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0xdc7c
movq %r15, %rdi
xorl %esi, %esi
movl $0x3, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x8630
movq %r13, %rdi
movq %r12, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
movq %r13, %rdi
movl $0x1, %esi
callq 0xe150
movq %r12, %rdi
movl $0x1, %esi
callq 0xe150
movq 0x18(%r12), %rax
movq %r12, %r13
cmpq %r14, %rax
jne 0x11567
movl $0x7, 0x70(%rax)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0xc0, %esi
movq %r14, %rdi
jmp 0x11656
movq %rax, %rbx
movl $0xc0, %esi
movq %r13, %rdi
jmp 0x11656
movq %rax, %rbx
movl $0xc0, %esi
movq 0x10(%rsp), %rdi
jmp 0x11656
movq %rax, %rbx
movq 0x28(%rsp), %rdi
cmpq %r15, %rdi
je 0x1165b
movq 0x38(%rsp), %rsi
incq %rsi
jmp 0x11656
movq %rax, %rbx
movl $0xc0, %esi
movq %r12, %rdi
callq 0x3220
movq %rbx, %rdi
callq 0x33e0
nop