//////////////////////////////////////////////////////////////////////
			// Code Example: Rollback 
			//
			//////////////////////////////////////////////////////////////////////

			// This function is passed the step number. This allows for an application to
			// produce code with several steps as demonstrated.
			// Return 1 if you have finished, 0 if otherwise and -1 to exit.

			int CMyCode::RunMyCode(int step)
			{

			//The code below is sample code. On exiting the function the bodies that
			//exist will be drawn

				
				static PK_BODY_t block, cylinder, sphere, sheet, new_sheet;
				static PK_PARTITION_t partition_1, partition_2;
				PK_AXIS2_sf_t axis_sf;
				PK_EDGE_t		edge = PK_ENTITY_null;
				int					nBlends		= 0;
				PK_FACE_t			*pBlends	= NULL;
				PK_FACE_array_t		*pFaces		= NULL;
				int					*pEdges		= NULL;	
				PK_blend_fault_t	fault		= PK_blend_fault_no_fault_c;
				PK_EDGE_t			fault_edge	= PK_ENTITY_null;
				PK_TOPOL_t			fault_topol	= PK_ENTITY_null;
				int			nBlendEdges		= 0;
				PK_EDGE_t	*pBlendEdges	= NULL;

				static PK_PARTITION_make_pmark_o_t make_opts = { 0 };
				static PK_PMARK_goto_o_t goto_opts = { 0 };

				static PK_PMARK_t	partition_1_pmark_1, partition_2_pmark_1, partition_1_pmark_2, partition_2_pmark_2;
				int n_new_entities = 0;
				PK_ENTITY_t *new_entities = NULL;
				int n_mod_entities = 0;
				PK_ENTITY_t *mod_entities = NULL;
				int n_del_entities = 0;
				PK_ENTITY_t *del_entities = NULL;
				PK_EDGE_set_blend_constant_o_t blend_opts;
				PK_BODY_fix_blends_o_t fix_opts;
				PK_BODY_section_o_t section_opts;
				PK_boolean_match_o_t section_match_opts;
				PK_TOPOL_track_r_t tracking;
				PK_section_2_r_t results; 
				PK_FACE_hollow_o_t hollow_opts;
				int n_faces;
				PK_FACE_t *faces = NULL;
				double offset_dist = 0;
				int n_bodies = 0;
				PK_BODY_t *bodies = NULL;
				PK_TOPOL_local_r_t local_res;
				CString text;
				int finished = 0;
				PK_TRANSF_t transf = PK_ENTITY_null;
				PK_VECTOR_t vector;
				PK_BODY_transform_o_t transf_opts;

				switch( step )
				{
				case 1:
			  
				/* Create the block
				 Size: 10 x 10 x 10.
				 Location & orientation: default (pass NULL as pointer to
				 the basis_set argument).                                   */
				/* Create the cylinder
				Radius: 2.5
				Height: 20.0
				Location & orientation: default.  */

				//create block and cylinder in current partition
					CExampleAppDoc::ExAppSetStatusBarString("Created a block and a cylinder in the current partition, partition_1");
						
					PK_SESSION_ask_curr_partition(&partition_1);
					PK_BODY_create_solid_block( 10.0, 10.0, 10.0, NULL, &block );

					// Make pmark 1 in partition 1
					PK_PARTITION_make_pmark_o_m(make_opts); /// Variable is static so value persists for future cases
					PK_PARTITION_make_pmark_2(partition_1, &make_opts, &partition_1_pmark_1, 
						&n_new_entities, &new_entities, &n_mod_entities, &mod_entities, &n_del_entities, &del_entities);
					if (n_new_entities)
						PK_MEMORY_free(new_entities);
					if (n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if (n_del_entities)
						PK_MEMORY_free(del_entities);

					// Create cylindrical solid body
					PK_BODY_create_solid_cyl( 2.5, 15.0, NULL, &cylinder );
					break;

				case 2:
			  //create new partition, change to it and create sheet and sphere
					CExampleAppDoc::ExAppSetStatusBarString("Created a new partition, partition_2, set this to the current partition and created a sphere and a planar sheet");
					PK_PARTITION_create_empty(&partition_2);
					PK_PARTITION_set_current(partition_2);

					axis_sf.location.coord[0] = 25;
					axis_sf.location.coord[1] = 0;
					axis_sf.location.coord[2] = 7;
					axis_sf.axis.coord[0] = 0;
					axis_sf.axis.coord[1] = 0;
					axis_sf.axis.coord[2] = 1;
					axis_sf.ref_direction.coord[0] = 1;
					axis_sf.ref_direction.coord[1] = 0;
					axis_sf.ref_direction.coord[2] = 0;
					PK_BODY_create_sheet_rectangle( 20.0, 20.0, &axis_sf, &sheet );

					// Make pmark 1 in partition 2
					PK_PARTITION_make_pmark_o_m(make_opts);
					PK_PARTITION_make_pmark_2(partition_2, &make_opts, &partition_2_pmark_1,
						&n_new_entities, &new_entities, &n_mod_entities, &mod_entities, &n_del_entities, &del_entities);
					if (n_new_entities)
						PK_MEMORY_free(new_entities);
					if (n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if (n_del_entities)
						PK_MEMORY_free(del_entities);

					axis_sf.location.coord[0] = 25;
					axis_sf.location.coord[1] = 0;
					axis_sf.location.coord[2] = 7;
					axis_sf.axis.coord[0] = 0;
					axis_sf.axis.coord[1] = 0;
					axis_sf.axis.coord[2] = 1;
					axis_sf.ref_direction.coord[0] = 1;
					axis_sf.ref_direction.coord[1] = 0;
					axis_sf.ref_direction.coord[2] = 0;
					PK_BODY_create_solid_sphere( 7.0, &axis_sf, &sphere );


					break;
				case 3: 
			//change to 1st partition and blend an edge of the block
					CExampleAppDoc::ExAppSetStatusBarString("Blended one edge of the block in partition_1");
					PK_EDGE_set_blend_constant_o_m( blend_opts );
					PK_BODY_fix_blends_o_m( fix_opts );
					
					// Make pmark 2 in partition 1
					PK_PARTITION_make_pmark_o_m(make_opts);
					PK_PARTITION_make_pmark_2(partition_1, &make_opts, &partition_1_pmark_2,
						&n_new_entities, &new_entities, &n_mod_entities, &mod_entities, &n_del_entities, &del_entities);
					if (n_new_entities)
						PK_MEMORY_free(new_entities);
					if (n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if (n_del_entities)
						PK_MEMORY_free(del_entities);
				
					PK_BODY_ask_first_edge(block, &edge);
					PK_EDGE_set_blend_constant(1, &edge, 1.0, &blend_opts, &nBlendEdges, &pBlendEdges);
					if ( nBlendEdges )
						PK_MEMORY_free( pBlendEdges );

					PK_BODY_fix_blends(block, &fix_opts, &nBlends, &pBlends, &pFaces, &pEdges, &fault, &fault_edge, &fault_topol);
					if ( nBlends )
					{
						PK_MEMORY_free( pBlends );
						PK_MEMORY_free( pFaces );
						PK_MEMORY_free( pEdges );
					}
					break;
				case 4:
			//change to 2nd partition and section the sphere with the sheet 
					CExampleAppDoc::ExAppSetStatusBarString("Sectioned the sphere with the sheet retaining the back bodies only in partition_2");
					PK_BODY_section_o_m( section_opts );	
					PK_boolean_match_o_m (section_match_opts);
					section_opts.fence = PK_section_fence_back_c;
					section_match_opts.match_style = PK_boolean_match_style_auto_c;	// match style "auto" is the recommended setting: typically gives highest likelihood of robustness
					PK_BODY_section_with_sheet_2(sphere, sheet, §ion_opts, &tracking, &results);
					PK_TOPOL_track_r_f( &tracking ); 
					PK_section_2_r_f( &results );   

					// Make pmark 2 in partition 2
					PK_PARTITION_make_pmark_o_m(make_opts);
					PK_PARTITION_make_pmark_2(partition_2, &make_opts, &partition_2_pmark_2,
						&n_new_entities, &new_entities, &n_mod_entities, &mod_entities, &n_del_entities, &del_entities);
					if (n_new_entities)
						PK_MEMORY_free(new_entities);
					if (n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if (n_del_entities)
						PK_MEMORY_free(del_entities);

					break;
				case 5: 
			//change to first partition and rollback the blend
					CExampleAppDoc::ExAppSetStatusBarString("Rolled back to before the edge blend in partition_1");

					PK_PMARK_goto_o_m(goto_opts); /// Variable is static so initialised value now persists for later cases
					PK_PMARK_goto_2(partition_1_pmark_2, &goto_opts, &n_new_entities, &new_entities, &n_mod_entities, &mod_entities,
						&n_del_entities, &del_entities);
					
					if(n_new_entities)
						PK_MEMORY_free(new_entities);
					if(n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if(n_del_entities)
						PK_MEMORY_free(del_entities);
					break;
				case 6:
			//change to second partition and hollow the sphere 
					CExampleAppDoc::ExAppSetStatusBarString("Hollowed the hemisphere in partition_2");
						
					PK_BODY_ask_faces(sphere, &n_faces, &faces);
					offset_dist = 1;
					PK_FACE_hollow_o_m( hollow_opts );
					hollow_opts.offset_method = PK_offset_method_sx_repair_2_c;
					PK_FACE_hollow_3(1, &faces[1], &offset_dist, 1.0e-06, &hollow_opts, &tracking, &local_res);
					PK_TOPOL_track_r_f( &tracking ); 
					PK_TOPOL_local_r_f( &local_res ); 
					if(n_faces)
						PK_MEMORY_free(faces);

					break;
				case 7: 
					CExampleAppDoc::ExAppSetStatusBarString("Subtracted the cylinder from the block in partition_1");
					PK_BODY_subtract_bodies(block, 1, &cylinder, &n_bodies, &bodies);
					if(n_bodies)
						PK_MEMORY_free( bodies );

					break;
				case 8:
					//change to second partition and undo hollow
					CExampleAppDoc::ExAppSetStatusBarString("Rolled back to before the hollow operation in partition_2");
					PK_PMARK_goto_2(partition_2_pmark_2, &goto_opts, &n_new_entities, &new_entities, &n_mod_entities, &mod_entities,
						&n_del_entities, &del_entities);
					if(n_new_entities)
						PK_MEMORY_free(new_entities);
					if(n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if(n_del_entities)
						PK_MEMORY_free(del_entities);

					break;
				case 9:
					//redo hollow with bigger radius and apply an edge blend
					CExampleAppDoc::ExAppSetStatusBarString("Performed the hollow operation with a larger offset distance and blended one edge in partition_2");
					PK_BODY_ask_faces(sphere, &n_faces, &faces);
					offset_dist = 1.75;
					PK_FACE_hollow_o_m( hollow_opts );
					hollow_opts.offset_method = PK_offset_method_sx_repair_2_c;

					PK_FACE_hollow_3(1, &faces[1], &offset_dist, 1.0e-06, &hollow_opts, &tracking, &local_res);
					
					PK_EDGE_set_blend_constant_o_m( blend_opts );
					PK_BODY_fix_blends_o_m( fix_opts );
					PK_BODY_ask_first_edge(sphere, &edge);
					PK_EDGE_set_blend_constant(1, &edge, 0.45, &blend_opts, &nBlendEdges, &pBlendEdges);
					if ( nBlendEdges )
						PK_MEMORY_free( pBlendEdges );

					PK_BODY_fix_blends(sphere, &fix_opts, &nBlends, &pBlends, &pFaces, &pEdges, &fault, &fault_edge, &fault_topol);
					PK_TOPOL_track_r_f( &tracking ); 
					PK_TOPOL_local_r_f( &local_res ); 
					PK_MEMORY_free(faces);
					if ( nBlends )
					{
						PK_MEMORY_free( pBlends );
						PK_MEMORY_free( pFaces );
						PK_MEMORY_free( pEdges );
					}
					break;
				case 10:
					CExampleAppDoc::ExAppSetStatusBarString("Rolled all the way back to just after the creation of the planar sheet body in partition_2");
					//go to second partition and go to where sheet was created
					PK_PMARK_goto_2(partition_2_pmark_1, &goto_opts, &n_new_entities, &new_entities, &n_mod_entities, &mod_entities,
						&n_del_entities, &del_entities);
					if(n_new_entities)
						PK_MEMORY_free(new_entities);
					if(n_mod_entities)
						PK_MEMORY_free(mod_entities);
					if(n_del_entities)
						PK_MEMORY_free(del_entities);
					break;
				case 11:
				// change the sheet to the block partition and translate it
					CExampleAppDoc::ExAppSetStatusBarString("Set the current partition to partition_2, copied the sheet body, translated it and changed it from partition_2 to partition_1");
					//note that PK_ENTITY_copy is a deprecated function, any new code should use the function that has superseded it
					PK_ENTITY_copy(sheet, &new_sheet);
					PK_ENTITY_delete(1, &sheet);
					vector.coord[0] = -25;
					vector.coord[1] = 0;
					vector.coord[2] = 0;
					PK_TRANSF_create_translation(vector, &transf);
					PK_BODY_transform_o_m( transf_opts );
					PK_BODY_transform_2(new_sheet, transf, 1.0e-06, &transf_opts, &tracking, &local_res);
					PK_TOPOL_track_r_f( &tracking ); 
					PK_TOPOL_local_r_f( &local_res ); 
					PK_BODY_change_partition(new_sheet, partition_1);
					break;
				case 12:
				// subtract the block form the sheet
					CExampleAppDoc::ExAppSetStatusBarString("Subtracted the block from the planar sheet");
					PK_BODY_subtract_bodies(new_sheet, 1, &block, &n_bodies, &bodies);
					if(n_bodies)
						PK_MEMORY_free(bodies);
					break;
				default:
					finished = 1;
				}

				return finished;
			}