// File: /workspace/github_cpp_makefile_star2_O2/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, 0x10(%rsp)
movq %rdi, %r14
leaq 0x4433(%rip), %rsi      # 0x1161d
leaq 0x28(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0x3e82
leaq 0x28(%rsp), %rdi
pushq $0x2
popq %r15
movl %r15d, %esi
callq 0x3d1a
leaq 0x28(%rsp), %rdi
callq 0x3458
movq 0x8(%r14), %rcx
movq (%rcx), %rax
movq 0x38(%rax), %rbx
movslq (%r14), %rax
xorl %edi, %edi
testl %eax, %eax
movl $0x0, %esi
cmovgl %eax, %esi
movq %rdi, %rdx
cmpq %rdi, %rsi
je 0xd245
movq (%rcx,%rdx,8), %r8
leaq 0x1(%rdx), %rdi
cmpb $0x0, 0x32(%r8)
jne 0xd22e
movslq 0x18(%r14), %rsi
movq 0x58(%rbx), %rcx
cmpl $0x0, (%rcx,%rsi,4)
je 0xd3e5
movq %rbx, %rdi
callq 0xc7d2
movq %r14, %rdi
callq 0xcc4e
movl (%r14), %eax
movq 0x8(%r14), %rcx
xorl %edx, %edx
testl %eax, %eax
cmovlel %edx, %eax
cmpq %rdx, %rax
je 0xd287
movq (%rcx,%rdx,8), %rsi
movb $0x0, 0x32(%rsi)
incq %rdx
jmp 0xd275
movslq 0x18(%r14), %rax
movq 0x58(%rbx), %rcx
movl %r15d, (%rcx,%rax,4)
movslq 0x1c(%r14), %rax
movl %r15d, (%rcx,%rax,4)
movl 0x38(%rbx), %r12d
movl $0xc0, %edi
callq 0x3240
movq %rax, %rbp
andq $0x0, (%rsp)
pushq $0x8
popq %rdx
pushq $0x3
popq %rcx
pushq $-0x1
popq %r9
movq %rax, %rdi
movq %rbx, %rsi
movl %r15d, %r8d
callq 0xa3fa
movl $0xc0, %edi
callq 0x3240
movq %rax, %r13
andq $0x0, (%rsp)
pushq $0x8
popq %rdx
pushq $0x3
popq %rcx
pushq $0x2
popq %r8
pushq $-0x1
popq %r9
movq %rax, %rdi
movq %rbx, 0x8(%rsp)
movq %rbx, %rsi
callq 0xa3fa
movq 0x8(%r14), %rax
movq 0x10(%r14), %rcx
movq (%rax), %rdi
movzbl (%rcx), %esi
xorl $0x1, %esi
shll $0x2, %esi
callq 0xf07a
movq 0x88(%rax), %rbx
leaq 0x18(%rsp), %rdi
pushq $0x1
popq %rsi
pushq $0x3
popq %r15
pushq $0x2
popq %r8
movl %r15d, %edx
xorl %ecx, %ecx
callq 0x6790
movq %rbp, %rdi
movq %rbx, %rsi
movl %r15d, %edx
leaq 0x18(%rsp), %rcx
callq 0xa5d2
movq 0x8(%r14), %rax
cmpb $0x1, 0x20(%r14)
jne 0xd3a4
movq (%rax), %rdi
movq 0x10(%r14), %rax
movzbl (%rax), %eax
xorl $0x1, %eax
leal (%rax,%rax,2), %esi
addl $0x2, %esi
callq 0xf07a
movq 0x88(%rax), %rax
movq 0x88(%rax), %rbx
leaq 0x18(%rsp), %rdi
pushq $0x1
popq %rdx
pushq $0x3
popq %r15
pushq $0x2
popq %r8
xorl %esi, %esi
movl %r15d, %ecx
callq 0x6790
movq %r13, %rdi
movq %rbx, %rsi
movl %r15d, %edx
leaq 0x18(%rsp), %rcx
jmp 0xd425
movslq (%r14), %rcx
movq -0x8(%rax,%rcx,8), %rdi
movq 0x10(%r14), %rax
movzbl -0x1(%rax,%rcx), %eax
leal (%rax,%rax,2), %esi
callq 0xf07a
movq 0x88(%rax), %rbx
movq 0x10(%r14), %rax
movslq (%r14), %rcx
cmpb $0x1, -0x1(%rax,%rcx)
jne 0xd401
leaq 0x18(%rsp), %rdi
pushq $0x3
popq %rdx
pushq $0x2
popq %rcx
pushq $0x1
popq %r8
xorl %esi, %esi
jmp 0xd412
cmpq %rax, %rdx
jl 0xd257
movslq 0x1c(%r14), %rax
cmpl $0x0, (%rcx,%rax,4)
je 0xd25f
jmp 0xd257
leaq 0x18(%rsp), %rdi
pushq $0x3
popq %rsi
pushq $0x1
popq %rdx
pushq $0x2
popq %rcx
xorl %r8d, %r8d
callq 0x6790
pushq $0x3
popq %rdx
leaq 0x18(%rsp), %rcx
movq %r13, %rdi
movq %rbx, %rsi
callq 0xa5d2
cmpl $0x1, 0x10(%rsp)
jne 0xd446
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
movl %r12d, %edx
callq 0xce9c
movq %rax, %r15
jmp 0xd449
movq %rbp, %r15
xorl %ebx, %ebx
movl (%r14), %eax
leal 0x2(,%rax,2), %eax
cmpl %eax, %ebx
jge 0xd470
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xd013
movq %rax, %r15
incl %ebx
jmp 0xd44b
cmpl $-0x1, 0x10(%rsp)
jne 0xd4c6
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xce9c
jmp 0xd4c3
movq %rax, %r15
movl $0xc0, %esi
movq %r13, %rdi
jmp 0xd6af
movq %rax, %r15
movl $0xc0, %esi
movq %rbp, %rdi
jmp 0xd6af
movq %rax, %r15
leaq 0x28(%rsp), %rdi
callq 0x3458
jmp 0xd6b4
movq %rax, %r15
jmp 0xd6b4
movq %rax, %r15
cmpq %r13, %r15
je 0xd4dd
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xd0ec
jmp 0xd4c3
cmpl $-0x1, 0x10(%rsp)
sete %al
movl $0x7, 0x70(%r15)
cmpb %al, 0x20(%r14)
jne 0xd4fa
movq 0x8(%rsp), %r13
jmp 0xd510
movq 0x8(%rsp), %r13
movq %r13, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xce9c
movq %rax, %r15
xorl %ebx, %ebx
movl (%r14), %eax
leal 0x2(,%rax,2), %eax
cmpl %eax, %ebx
jge 0xd535
movq %r13, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xd013
movq %rax, %r15
incl %ebx
jmp 0xd512
cmpl $0x1, 0x10(%rsp)
sete %al
cmpb %al, 0x20(%r14)
je 0xd554
movq %r13, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xce9c
movq %rax, %r15
cmpq %rbp, %r15
je 0xd569
movq %r13, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0xd0ec
jmp 0xd551
movl $0x7, 0x70(%r15)
movl $0xc0, %edi
callq 0x3240
movq %rax, %rbx
andq $0x0, (%rsp)
pushq $0x8
popq %rdx
pushq $0x3
popq %rcx
pushq $0x2
popq %r8
pushq $-0x1
popq %r9
movq %rax, 0x10(%rsp)
movq %rax, %rdi
movq %r13, %rsi
callq 0xa3fa
cmpq $0x0, 0x10(%r15)
je 0xd5c2
cmpq $0x0, 0x18(%r15)
je 0xd5d5
leaq 0x18(%rsp), %rdi
pushq $0x3
popq %rsi
pushq $0x1
popq %rcx
pushq $0x2
popq %r8
xorl %edx, %edx
jmp 0xd5e6
leaq 0x18(%rsp), %rdi
pushq $0x3
popq %rsi
pushq $0x1
popq %rdx
pushq $0x2
popq %rcx
xorl %r8d, %r8d
jmp 0xd5e6
leaq 0x18(%rsp), %rdi
pushq $0x3
popq %rsi
pushq $0x2
popq %rdx
pushq $0x1
popq %r8
xorl %ecx, %ecx
callq 0x6790
pushq $0x3
popq %rbp
leaq 0x18(%rsp), %rcx
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %edx
callq 0xa5d2
pushq $0x1
popq %r15
pushq $0x2
popq %r13
leaq 0x48(%rsp), %r12
movq %rbx, %rdi
movl %r15d, %esi
callq 0xa81a
movq 0x18(%rbx), %rax
cmpq 0x10(%rsp), %rax
je 0xd681
movl $0xc0, %edi
callq 0x3240
movq %rax, %r14
andq $0x0, (%rsp)
movq %rax, %rdi
movq 0x8(%rsp), %rsi
pushq $0x7
popq %rdx
movl %ebp, %ecx
movl %r13d, %r8d
pushq $-0x1
popq %r9
callq 0xa3fa
movq %r12, %rdi
xorl %esi, %esi
movl %ebp, %edx
movl %r15d, %ecx
movl %r13d, %r8d
callq 0x6790
movq %rbx, %rdi
movq %r14, %rsi
movl %r15d, %edx
movq %r12, %rcx
callq 0xa734
movq %rbx, %rdi
movl %r15d, %esi
callq 0xa81a
movq %r14, %rbx
jmp 0xd60d
movl $0x7, 0x70(%rax)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r15
movl $0xc0, %esi
movq %rbx, %rdi
jmp 0xd6af
movq %rax, %r15
movl $0xc0, %esi
movq %r14, %rdi
callq 0x3250
movq %r15, %rdi
callq 0x33d0