// File: 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
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq -0x31(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x3560
movq -0xe8(%rbp), %rdx
leaq 0xaa86(%rip), %rsi      # 0x27601
leaq -0x30(%rbp), %rdi
callq 0x4e10
jmp 0x1cb86
leaq -0x30(%rbp), %rdi
movl $0x2, %esi
callq 0x4c10
jmp 0x1cb96
leaq -0x30(%rbp), %rdi
callq 0x35f8
leaq -0x31(%rbp), %rdi
callq 0x3360
movq -0xf0(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x38(%rax), %rax
movq %rax, -0x50(%rbp)
movb $0x0, -0x51(%rbp)
movl $0x0, -0x58(%rbp)
movq -0xf0(%rbp), %rcx
movl -0x58(%rbp), %eax
cmpl (%rcx), %eax
jge 0x1cc37
movq -0xf0(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x58(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x211c0
testb $0x1, %al
jne 0x1cc2a
movb $0x1, -0x51(%rbp)
jmp 0x1cc37
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x1cc1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x35f8
leaq -0x31(%rbp), %rdi
callq 0x3360
jmp 0x1d48f
jmp 0x1cc2c
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x1cbc9
movq -0xf0(%rbp), %rax
movq -0x50(%rbp), %rdi
addq $0x58, %rdi
movslq 0x18(%rax), %rsi
callq 0x9af0
cmpl $0x0, (%rax)
jne 0x1cc71
movq -0xf0(%rbp), %rax
movq -0x50(%rbp), %rdi
addq $0x58, %rdi
movslq 0x1c(%rax), %rsi
callq 0x9af0
cmpl $0x0, (%rax)
je 0x1cc75
movb $0x1, -0x51(%rbp)
testb $0x1, -0x51(%rbp)
je 0x1cc84
movq -0x50(%rbp), %rdi
callq 0x1b770
movq -0xf0(%rbp), %rdi
callq 0x1c020
movl $0x0, -0x5c(%rbp)
movq -0xf0(%rbp), %rcx
movl -0x5c(%rbp), %eax
cmpl (%rcx), %eax
jge 0x1ccca
movq -0xf0(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
xorl %esi, %esi
callq 0x9b30
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x1cc97
movq -0xf0(%rbp), %rax
movq -0x50(%rbp), %rdi
addq $0x58, %rdi
movslq 0x18(%rax), %rsi
callq 0x9af0
movq %rax, %rcx
movq -0xf0(%rbp), %rax
movl $0x2, (%rcx)
movq -0x50(%rbp), %rdi
addq $0x58, %rdi
movslq 0x1c(%rax), %rsi
callq 0x9af0
movl $0x2, (%rax)
movq -0x50(%rbp), %rdi
callq 0x20e40
movl %eax, -0x60(%rbp)
movl $0xc0, %edi
callq 0x3300
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xf8(%rbp)
movq -0x50(%rbp), %rsi
movq %rsp, %rax
movq $0x0, (%rax)
movl $0x8, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0x17070
jmp 0x1cd57
movq -0xf8(%rbp), %rax
movq %rax, -0x68(%rbp)
movl $0xc0, %edi
callq 0x3300
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x100(%rbp)
movq -0x50(%rbp), %rsi
movq %rsp, %rax
movq $0x0, (%rax)
movl $0x8, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0x17070
jmp 0x1cda4
movq -0xf0(%rbp), %rax
movq -0x100(%rbp), %rcx
movq %rcx, -0x70(%rbp)
movq -0x68(%rbp), %rcx
movq %rcx, -0x110(%rbp)
movq 0x8(%rax), %rcx
movq (%rcx), %rdi
movq 0x10(%rax), %rax
movb (%rax), %cl
movl $0x4, %esi
xorl %eax, %eax
testb $0x1, %cl
cmovnel %eax, %esi
callq 0x20eb0
movq %rax, %rdi
callq 0x20e60
movq %rax, %rcx
movq -0xf0(%rbp), %rax
movq %rcx, -0x108(%rbp)
movq 0x10(%rax), %rax
testb $0x1, (%rax)
je 0x1ce1f
leaq -0x80(%rbp), %rdi
movl $0x1, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x9cc0
jmp 0x1ce3a
leaq -0x80(%rbp), %rdi
movl $0x1, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x9cc0
movq -0x108(%rbp), %rsi
movq -0x110(%rbp), %rdi
movl $0x3, %edx
leaq -0x80(%rbp), %rcx
callq 0x17390
movq -0xf0(%rbp), %rax
testb $0x1, 0x20(%rax)
je 0x1cf6b
movq -0xf0(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, -0x120(%rbp)
movq 0x8(%rax), %rcx
movq (%rcx), %rdi
movq 0x10(%rax), %rax
movb (%rax), %cl
movl $0x5, %esi
movl $0x2, %eax
testb $0x1, %cl
cmovnel %eax, %esi
callq 0x20eb0
movq %rax, %rdi
callq 0x20e60
movq %rax, %rdi
callq 0x20e60
movq %rax, %rcx
movq -0xf0(%rbp), %rax
movq %rcx, -0x118(%rbp)
movq 0x10(%rax), %rax
testb $0x1, (%rax)
je 0x1cee5
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x9cc0
jmp 0x1cf03
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x9cc0
movq -0x118(%rbp), %rsi
movq -0x120(%rbp), %rdi
movl $0x3, %edx
leaq -0x90(%rbp), %rcx
callq 0x17390
jmp 0x1d033
movq -0xf8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0xc0, %esi
callq 0x3310
jmp 0x1d48f
movq -0x100(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0xc0, %esi
callq 0x3310
jmp 0x1d48f
movq -0xf0(%rbp), %rcx
movq -0x70(%rbp), %rax
movq %rax, -0x130(%rbp)
movq 0x8(%rcx), %rax
movl (%rcx), %edx
subl $0x1, %edx
movslq %edx, %rdx
movq (%rax,%rdx,8), %rdi
movq 0x10(%rcx), %rax
movl (%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %cl
xorl %esi, %esi
movl $0x3, %eax
testb $0x1, %cl
cmovnel %eax, %esi
callq 0x20eb0
movq %rax, %rdi
callq 0x20e60
movq -0xf0(%rbp), %rcx
movq %rax, -0x128(%rbp)
movq 0x10(%rcx), %rax
movl (%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
testb $0x1, (%rax,%rcx)
je 0x1cff6
leaq -0xa0(%rbp), %rdi
xorl %esi, %esi
movl $0x3, %edx
movl $0x2, %ecx
movl $0x1, %r8d
callq 0x9cc0
jmp 0x1d014
leaq -0xa0(%rbp), %rdi
movl $0x3, %esi
movl $0x1, %edx
movl $0x2, %ecx
xorl %r8d, %r8d
callq 0x9cc0
movq -0x128(%rbp), %rsi
movq -0x130(%rbp), %rdi
movl $0x3, %edx
leaq -0xa0(%rbp), %rcx
callq 0x17390
movq -0x68(%rbp), %rax
movq %rax, -0xa8(%rbp)
cmpl $0x1, -0xc(%rbp)
jne 0x1d05e
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c580
movq %rax, -0xa8(%rbp)
movl $0x0, -0xac(%rbp)
movq -0xf0(%rbp), %rcx
movl -0xac(%rbp), %eax
movl (%rcx), %ecx
shll %ecx
addl $0x2, %ecx
cmpl %ecx, %eax
jge 0x1d0ab
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c820
movq %rax, -0xa8(%rbp)
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x1d068
cmpl $-0x1, -0xc(%rbp)
jne 0x1d0cb
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c580
movq %rax, -0xa8(%rbp)
jmp 0x1d0cd
movq -0xa8(%rbp), %rax
cmpq -0x70(%rbp), %rax
je 0x1d0f6
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c9a0
movq %rax, -0xa8(%rbp)
jmp 0x1d0cd
movq -0xa8(%rbp), %rdi
movl $0x7, %esi
callq 0x20f50
movq -0xf0(%rbp), %rcx
cmpl $-0x1, -0xc(%rbp)
sete %al
andb $0x1, %al
movzbl %al, %eax
movb 0x20(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
je 0x1d144
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c580
movq %rax, -0xa8(%rbp)
movl $0x0, -0xb0(%rbp)
movq -0xf0(%rbp), %rcx
movl -0xb0(%rbp), %eax
movl (%rcx), %ecx
shll %ecx
addl $0x2, %ecx
cmpl %ecx, %eax
jge 0x1d191
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c820
movq %rax, -0xa8(%rbp)
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0x1d14e
movq -0xf0(%rbp), %rcx
cmpl $0x1, -0xc(%rbp)
sete %al
andb $0x1, %al
movzbl %al, %eax
movb 0x20(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
je 0x1d1ce
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c580
movq %rax, -0xa8(%rbp)
jmp 0x1d1d0
movq -0xa8(%rbp), %rax
cmpq -0x68(%rbp), %rax
je 0x1d1f9
movq -0x50(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0x60(%rbp), %edx
callq 0x1c9a0
movq %rax, -0xa8(%rbp)
jmp 0x1d1d0
movq -0xa8(%rbp), %rdi
movl $0x7, %esi
callq 0x20f50
movl $0xc0, %edi
callq 0x3300
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x138(%rbp)
movq -0x50(%rbp), %rsi
movq %rsp, %rax
movq $0x0, (%rax)
movl $0x8, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0x17070
jmp 0x1d24c
movq -0x138(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xa8(%rbp), %rdi
xorl %esi, %esi
callq 0x20b60
cmpq $0x0, %rax
jne 0x1d28e
leaq -0xc8(%rbp), %rdi
movl $0x3, %esi
movl $0x1, %edx
movl $0x2, %ecx
xorl %r8d, %r8d
callq 0x9cc0
jmp 0x1d2e5
movq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x20b60
cmpq $0x0, %rax
jne 0x1d2c5
leaq -0xc8(%rbp), %rdi
movl $0x3, %esi
movl $0x2, %edx
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0x9cc0
jmp 0x1d2e3
leaq -0xc8(%rbp), %rdi
movl $0x3, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x9cc0
jmp 0x1d2e5
movq -0xb8(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl $0x3, %edx
leaq -0xc8(%rbp), %rcx
callq 0x17390
movq -0xb8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x177f0
movq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x20b60
cmpq -0xb8(%rbp), %rax
je 0x1d45d
movl $0xc0, %edi
callq 0x3300
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x140(%rbp)
movq -0x50(%rbp), %rsi
movq %rsp, %rax
movq $0x0, (%rax)
movl $0x7, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0x17070
jmp 0x1d383
movq -0x140(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0x150(%rbp)
movq -0xd0(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0xe0(%rbp), %rdi
xorl %esi, %esi
movl $0x3, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x9cc0
movq -0x150(%rbp), %rdi
movq -0x148(%rbp), %rsi
movl $0x1, %edx
leaq -0xe0(%rbp), %rcx
callq 0x17650
movq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x177f0
movq -0xd0(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x177f0
jmp 0x1d323
movq -0x138(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0xc0, %esi
callq 0x3310
jmp 0x1d48f
movq -0x140(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0xc0, %esi
callq 0x3310
jmp 0x1d48f
movq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x20b60
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
movl $0x7, %esi
callq 0x20f50
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x3550
nopl (%rax,%rax)