//////////////////////////////////////////////////////////////////////
// Code Example: Attribute callbacks
//
//////////////////////////////////////////////////////////////////////
// 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;
static PK_BODY_t sheet;
PK_FACE_t *faces = NULL;
PK_PART_t *parts = NULL;
int n_faces = 0;
int n_parts = 0;
CString text;
int finished = 0;
double cols[] = {1., 0., 0.};
static PK_ATTDEF_t attdef;
PK_AXIS2_sf_t basis_set;
PK_BODY_section_o_t options;
PK_TOPOL_track_r_t tracking;
PK_section_2_r_t results;
PK_ATTDEF_callback_flags_t flags;
switch( step )
{
case 1:
CExampleAppDoc::ExAppSetStatusBarString("Registered merge and split callback functions for the colour attribute in CSession::RegisterCallbacks. Created a solid block");
PK_BODY_create_solid_block( 10.0, 10.0, 10.0, NULL, &block );
break;
case 2:
CExampleAppDoc::ExAppSetStatusBarString("Coloured all faces of the solid block red");
PK_BODY_ask_faces(block, &n_faces, &faces);
PK_ATTRIB_t attrib;
int i;
PK_ATTDEF_find("SDL/TYSA_COLOUR", &attdef);
for(i=0; i< n_faces; i++)
{
PK_ATTRIB_create_empty(faces[i], attdef, &attrib);
PK_ATTRIB_set_doubles(attrib, 0, 3, cols);
}
if(n_faces)
PK_MEMORY_free(faces);
break;
case 3:
CExampleAppDoc::ExAppSetStatusBarString("Created sheet rectangle");
basis_set.location.coord[0] = 0;
basis_set.location.coord[1] = 0;
basis_set.location.coord[2] = 5;
basis_set.axis.coord[0] = 0;
basis_set.axis.coord[1] = 0;
basis_set.axis.coord[2] = 1;
basis_set.ref_direction.coord[0] = 1;
basis_set.ref_direction.coord[1] = 0;
basis_set.ref_direction.coord[2] = 0;
PK_BODY_create_sheet_rectangle( 20.0, 20.0, &basis_set, &sheet );
break;
case 4:
CExampleAppDoc::ExAppSetStatusBarString("Performed section retaining the front body. One new face created in the default grey colour, split faces retain the red colour");
PK_BODY_section_o_m( options );
options.fence = PK_section_fence_front_c;
PK_BODY_section_with_sheet_2(block, sheet, &options, &tracking, &results);
PK_TOPOL_track_r_f( &tracking );
PK_section_2_r_f( &results );
break;
case 5:
CExampleAppDoc::ExAppSetStatusBarString("Deleted all bodies and switched on the merge and split attribute callbacks");
flags.split_callback_on = PK_LOGICAL_true;
flags.merge_callback_on = PK_LOGICAL_true;
flags.copy_callback_on = PK_LOGICAL_false;
flags.delete_callback_on = PK_LOGICAL_false;
flags.receive_callback_on = PK_LOGICAL_false;
flags.transmit_callback_on = PK_LOGICAL_false;
PK_ATTDEF_set_callback_flags(attdef, &flags);
PK_SESSION_ask_parts(&n_parts, &parts);
if(n_parts)
{
PK_ENTITY_delete(n_parts, parts);
PK_MEMORY_free(parts);
}
break;
case 6:
CExampleAppDoc::ExAppSetStatusBarString("Created the red block and sheet again");
PK_BODY_create_solid_block( 10.0, 10.0, 10.0, NULL, &block );
PK_BODY_ask_faces(block, &n_faces, &faces);
for(i=0; i< n_faces; i++)
{
PK_ATTRIB_create_empty(faces[i], attdef, &attrib);
PK_ATTRIB_set_doubles(attrib, 0, 3, cols);
}
if(n_faces)
PK_MEMORY_free(faces);
basis_set.location.coord[0] = 0;
basis_set.location.coord[1] = 0;
basis_set.location.coord[2] = 5;
basis_set.axis.coord[0] = 0;
basis_set.axis.coord[1] = 0;
basis_set.axis.coord[2] = 1;
basis_set.ref_direction.coord[0] = 1;
basis_set.ref_direction.coord[1] = 0;
basis_set.ref_direction.coord[2] = 0;
PK_BODY_create_sheet_rectangle( 20.0, 20.0, &basis_set, &sheet );
break;
case 7:
CExampleAppDoc::ExAppSetStatusBarString("Performed section retaining both bodies. Split faces are now blue with a new green face (CSession::ColourSplitCallback)");
PK_BODY_section_o_m( options );
PK_BODY_section_with_sheet_2(block, sheet, &options, &tracking, &results);
PK_TOPOL_track_r_f( &tracking );
PK_section_2_r_f( &results );
break;
case 8:
CExampleAppDoc::ExAppSetStatusBarString("Performed boolean unite between the two bodies. Merged faces combined to form one black face (CSession::ColourMergeCallback)");
PK_BODY_boolean_o_t bool_opts;
PK_BODY_boolean_o_m( bool_opts );
PK_boolean_r_t bool_res;
bool_opts.merge_imprinted = PK_LOGICAL_true;
PK_SESSION_ask_parts(&n_parts, &parts);
PK_BODY_boolean_2(parts[0], 1, &parts[1], &bool_opts, &tracking, &bool_res);
PK_TOPOL_track_r_f( &tracking );
PK_boolean_r_f( &bool_res );
break;
default:
flags.split_callback_on = PK_LOGICAL_false;
flags.merge_callback_on = PK_LOGICAL_false;
flags.copy_callback_on = PK_LOGICAL_false;
flags.delete_callback_on = PK_LOGICAL_false;
flags.receive_callback_on = PK_LOGICAL_false;
flags.transmit_callback_on = PK_LOGICAL_false;
PK_ATTDEF_set_callback_flags(attdef, &flags);
finished = 1;
}
return finished;
}
//////////////////////////////////////////////////////////////////////
Session.h
#include "parasolid_kernel.h"
class CSession
{
public:
BOOL Start();
BOOL Stop();
static void ReturnMemory(int * nBytes, char * * memory, int * ifail);
static void GetMemory(int * nBytes, char * * memory, int * ifail);
static void StopFrustrum( int * ifail );
static void StartFrustrum( int * ifail );
static PK_ERROR_code_t PKerrorHandler( PK_ERROR_sf_t* error );
CSession();
~CSession();
private:
static void ColourSplitCallback(PK_ENTITY_t old_entity,
int n_attribs, const PK_ATTRIB_t attribs[],
PK_ENTITY_t new_entity );
static void ColourMergeCallback(PK_ENTITY_t live_entity,
int n_live_attribs, const PK_ATTRIB_t live_attribs[],
PK_ENTITY_t doomed_entity,
int n_doomed_attribs, const PK_ATTRIB_t doomed_attribs[]);
void RegisterCallbacks();
};
//////////////////////////////////////////////////////////////////////
Session.cpp
#include "Session.h"
#include "parasolid_kernel.h"
#include "frustrum_ifails.h"
// The following are frustrum function declarations
extern void StartFileFrustrum( int *);
extern void AbortFrustrum( int *);
extern void StopFileFrustrum( int *);
extern void OpenReadFrustrumFile( const int *, const int *, const char *, const int *,
const int *, int *, int *);
extern void OpenWriteFrustrumFile( const int *, const int *, const char *, const int *,
const char *, const int *, int *, int *);
extern void CloseFrustrumFile( const int *, const int *, const int *, int *);
extern void ReadFromFrustrumFile( const int *, const int *, const int *, char *, int *,
int *);
extern void WriteToFrustrumFile( const int *, const int *, const int *, const char *,
int *);
extern int SeekXT(const int, const int, unsigned int, unsigned int);
// The following are for the delta frustrum
extern "C" {
PK_ERROR_code_t FRU_delta_open_for_write(PK_PMARK_t, PK_DELTA_t *);
PK_ERROR_code_t FRU_delta_open_for_read(PK_DELTA_t);
PK_ERROR_code_t FRU_delta_write(PK_DELTA_t, unsigned, const char *);
PK_ERROR_code_t FRU_delta_read(PK_DELTA_t, unsigned, char *);
PK_ERROR_code_t FRU_delta_delete(PK_DELTA_t);
PK_ERROR_code_t FRU_delta_close(PK_DELTA_t);
int FRU__delta_init( int action );
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSession::CSession()
{
// Start up Parasolid
if ( !Start() )
exit(0);
}
CSession::~CSession()
{
// Close down Parasolid
Stop();
}
// Starts up Parasolid Session, returns true is successful, false otherwise.
BOOL CSession::Start()
{
BOOL ok = TRUE;
// Register frustrum functions
// Note: the GO functions are registered in CExampleAppDoc
PK_FSTART_f_t sf = StartFrustrum;
PK_FABORT_f_t af = AbortFrustrum;
PK_FSTOP_f_t stf = StopFrustrum;
PK_FMALLO_f_t gm = GetMemory;
PK_FMFREE_f_t rm = ReturnMemory;
PK_FFOPRD_f_t orf = OpenReadFrustrumFile;
PK_FFOPWR_f_t ow = OpenWriteFrustrumFile;
PK_FFCLOS_f_t cf = CloseFrustrumFile;
PK_FFREAD_f_t rf = ReadFromFrustrumFile;
PK_FFWRIT_f_t wf = WriteToFrustrumFile;
PK_FFSKXT_f_t sk = SeekXT;
PK_SESSION_register_fru_o_t fru_opts;
PK_SESSION_register_fru_o_m(fru_opts);
fru_opts.fstart = &sf;
fru_opts.fabort = ⁡
fru_opts.fstop = &stf;
fru_opts.fmallo = &gm;
fru_opts.fmfree = &rm;
fru_opts.ffoprd = &orf;
fru_opts.ffopwr = &ow;
fru_opts.ffclos = &cf;
fru_opts.ffread = &rf;
fru_opts.ffwrit = &wf;
fru_opts.ffskxt = &sk;
VERIFY(PK_SESSION_register_fru_2(&fru_opts) == PK_ERROR_no_errors);
// Register Delta Frustrum
PK_DELTA_frustrum_t delta_fru;
delta_fru.open_for_write_fn = FRU_delta_open_for_write;
delta_fru.open_for_read_fn = FRU_delta_open_for_read;
delta_fru.close_fn = FRU_delta_close;
delta_fru.write_fn = FRU_delta_write;
delta_fru.read_fn = FRU_delta_read;
delta_fru.delete_fn = FRU_delta_delete;
VERIFY(PK_DELTA_register_callbacks(delta_fru) == PK_ERROR_no_errors);
// Register Error Handler
PK_ERROR_frustrum_t errorFru;
errorFru.handler_fn = PKerrorHandler;
VERIFY( PK_ERROR_register_callbacks( errorFru ) == PK_ERROR_no_errors );
// Starts the modeller
PK_SESSION_start_o_t options;
PK_SESSION_start_o_m( options );
// By default session journalling is turned off, to enable set options.journal_file
// to where you want this data to be written to.
// eg.
// options.journal_file = "c:\\temp\\test";
PK_SESSION_start( &options );
RegisterCallbacks();
// Check to see if it all started up OK
PK_LOGICAL_t was_error = PK_LOGICAL_true;
PK_ERROR_sf_t error_sf;
PK_ERROR_ask_last( &was_error, &error_sf );
if ( was_error )
return false;
// Enable latest behaviour
PK_SESSION_behaviour_t behaviour_requested;
behaviour_requested.behaviour_type = PK_SESSION_behave_as_latest_c;
behaviour_requested.behaviour_value = 0;
PK_SESSION_set_behaviour_o_t behaviour_opts;
PK_SESSION_set_behaviour_o_m(behaviour_opts);
PK_SESSION_behaviour_t behaviour_set;
PK_SESSION_behaviour_t behaviour_previous;
PK_behaviour_status_t behaviour_status;
PK_SESSION_set_behaviour(behaviour_requested, &behaviour_opts, &behaviour_set, &behaviour_previous, &behaviour_status);
// A production application would check for errors and inspect the fields of behaviour_set,
// behaviour_previous and behaviour_status to confirm the requested behaviour was recognised
return ok;
}
BOOL CSession::Stop()
{
PK_SESSION_stop();
return TRUE;
}
void CSession::StartFrustrum(int * ifail)
{
*ifail = FR_no_errors;
FRU__delta_init( 1 );
StartFileFrustrum( ifail );
}
void CSession::StopFrustrum(int * ifail)
{
*ifail = FR_no_errors;
FRU__delta_init( 2 );
StopFileFrustrum( ifail );
}
void CSession::GetMemory(int * nBytes, char * * memory, int * ifail)
{
*memory = new char[ *nBytes ];
*ifail = (*memory) ? FR_no_errors : FR_memory_full;
}
void CSession::ReturnMemory(int * nBytes, char * * memory, int * ifail)
{
delete[] *memory;
*ifail = FR_no_errors;
}
PK_ERROR_code_t CSession::PKerrorHandler( PK_ERROR_sf_t* error )
{
char text[500];
sprintf_s(text, 500, "PK error: %s returned %s.", error->function,
error->code_token);
AfxMessageBox(CString(text));
return error->code;
}
void CSession::RegisterCallbacks()
{
PK_ATTDEF_t attdef;
PK_ATTDEF_callback_fns_s callbacks;
PK_ATTDEF_find("SDL/TYSA_COLOUR", &attdef);
callbacks.split_fn = ColourSplitCallback;
callbacks.merge_fn = ColourMergeCallback;
PK_ATTDEF_register_cb_o_t callback_opts;
PK_ATTDEF_register_cb_o_m (callback_opts);
PK_ATTDEF_register_cb(attdef, &callbacks, &callback_opts);
}
void CSession::ColourMergeCallback(PK_ENTITY_t live_entity,
int n_live_attribs, const PK_ATTRIB_t live_attribs[],
PK_ENTITY_t doomed_entity,
int n_doomed_attribs, const PK_ATTRIB_t doomed_attribs[] )
{
//live entity will be coloured black
double cols[] = {0., 0., 0.};
PK_ATTDEF_t attdef;
PK_ATTRIB_t attrib;
PK_ENTITY_delete(1, &live_attribs[0]);
PK_ATTDEF_find("SDL/TYSA_COLOUR", &attdef);
PK_ATTRIB_create_empty(live_entity, attdef, &attrib);
PK_ATTRIB_set_doubles(attrib, 0, 3, cols);
}
void CSession::ColourSplitCallback(PK_ENTITY_t old_entity,
int n_attribs, const PK_ATTRIB_t attribs[],
PK_ENTITY_t new_entity )
{
//new entity will be coloured green
double cols[] = {0., 1., 0.};
PK_ATTDEF_t attdef;
PK_ATTRIB_t attrib;
PK_ATTDEF_find("SDL/TYSA_COLOUR", &attdef);
PK_ATTRIB_create_empty(new_entity, attdef, &attrib);
PK_ATTRIB_set_doubles(attrib, 0, 3, cols);
//old entity will be coloured blue
double cols1[] = {0., 0., 1.};
PK_ENTITY_delete(1, &attribs[0]);
PK_ATTRIB_create_empty(old_entity, attdef, &attrib);
PK_ATTRIB_set_doubles(attrib, 0, 3, cols1);
}