//////////////////////////////////////////////////////////////////////
// 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;
}