Tolerant Stitching Sample Code


The following sample code demonstrates how to typically perform tolerant stitching using api_stitch and api_stitch_nonmanifold.

// Initialization of parameters common to api_stitch and api_stitch_nonmanifold 
// Create a default tolerant_stitch_options object.

tolerant_stitch_options sopts;


// Set the stitcher coincident face identification routine to SPASTITCH_COIN_SKIP to turn on 
// coincident face detection.

STITCH_COIN_MODES mode = SPASTITCH_COIN_SKIP;
sopts.set_stch_coincident_face_handling_mode(mode);


// Pointer to an array of ENTITY_LIST pointers to store the coincident face cluster lists. 
// This would probably be passed in by caller to allow list processing.       

ENTITY_LIST* coin_face_list = NULL;


// Set other optional stitch parameters, such as maximum stitch tolerance

...


// Make the careful option OFF to enable failsafe behavior
// Note:  By default the "careful" option is already OFF

option_header *careful_opt = find_option("careful");
if (NULL != careful_opt)
{
  careful_opt->push(FALSE);
}

// Note: To disable the failsafe behavior, set the careful" option ON (push TRUE) 


// List containing bodies output from api_stitch and api_stitch_nonmanifold. 
// This is the complete set of bodies that belong to the caller. 

ENTITY_LIST output_bodies;


// List will contain all the new bodies resulting from the API. This list will be a 
// subset of ENTITY_LIST& output_bodies. This list is provided so that it is 
// convenient to the caller to find out the new bodies that the caller will have to 
// take ownership of (for example, the users may have to register new bodies in their 
// application and/or do memory management for those bodies).

ENTITY_LIST new_bodies;

 
//Initialization of parameters specific to api_stitch 
// For the input parameter lists for TOLERANT_STITCH, the caller must fill pointers to 
// BODYs or free FACEs. A free FACE is a FACE that is a top-level entity and has no owner. 
// Note that free FACEs are not legal in ACIS, but the API still accepts them. However, 
// we recommend that the API be passed only BODYs.
 
// List containing the entities to be stitched

ENTITY_LIST to_be_stitched;


// Fill the list with entities to be stitched.

...


// Make a call to api_stitch to stitch the entities in "to be stitched" list 

outcome result_stch = api_stitch (to_be_stitched, output_bodies, new_bodies, &sopts);


//Initialization of parameters specific to api_stitch_nonmanifold
// For the input parameter lists for TOLERANT_STITCH, the caller must fill pointers to 
// BODYs or free FACEs. A free FACE is a FACE that is a top-level entity and has no owner. 
// Note that free FACEs are not legal in ACIS, but the API still accepts them. However, 
// we recommend that the API be passed only BODYs.

// List containing the entities to be stitched

ENTITY_LIST parting_faces;
ENTITY_LIST primary_bodies;


// Fill the parting_faces and primary_bodies list. The parting_faces list must contain 
// entities that need to be stitched with the entities in the primary_bodies list.

...


// Make a call to api_stitch_nonmanifold to stitch the entities in the “parting_faces and primary_bodies list”

outcome result_stch = api_stitch_nonmanifold(parting_faces, primary_bodies, output_bodies, new_bodies, &sopts);

 
//Code demonstrating analysis of results of api_stitch and api_stitch_nonmanifold
// Restore the original value of careful_opt

if (NULL != careful_opt)
{
 careful_opt->pop();
}

if ( !result_stch.ok() )
{


// User may want to know about the fatal error due to which the API failed

   error_info* einf = result_stch.get_error_info();


// User code to report information on errors. A sample function "display_problems_encountered" 
// for such reporting is given at the bottom of the code snippet

display_problems_encountered(einf);


 // Reasons for error

   if (einf->has_reasons())
   {
      // User code to mention that the following are reasons for the error, the user may print it as

      printf("Following are the reasons for the error: \n");
         
      // error_info_list owns all the error_info objects inside it and cleans them up on destruction.

      // User need not worry about memory cleanup of the error_info objects.

      error_info_list reasons_eil;
      einf->reasons(reasons_eil);

      const error_info* reason_einf = NULL;
      for (reasons_eil.init(); NULL != (reason_einf =       reasons_eil.next());)
      {
         display_problems_encountered(reason_einf);
      }
    }
 // User code to handle failure and exit
    ...
}


// Code demonstrating handling new bodies returned by api_stitch and api_stitch_nonmanifold
 
BODY *new_body = NULL;
new_bodies.init();
while (NULL != (new_body = (BODY *)new_bodies.next()))
{
 // User code to handle new bodies created by api_stitch and api_stitch_nonmnaifold. For example, 
 // the user may want to register new bodies into their application
    ...
}
 
 
// Code demonstrating problem reporting by api_stitch and api_stitch_nonmanifold
// API succeeded (either partially or fully) if this point is reached

error_info_list eil;
result_stch.get_error_info_list(eil);
const error_info* einf = NULL;
for (eil.init(); NULL != (einf = eil.next());)
{
 // User code to report information on problems. A sample function "display_problems_encountered" 
 // for such reporting is given at the bottom of the code snippet.

    display_problems_encountered(einf);

 // Reasons for the problem

    if (einf->has_reasons())
    {
        // User code to mention that the following are reasons for the problem,
        // the user may print it as

           printf("Following are the reasons for the problem: \n");

        // error_info_list owns all the error_info objects inside it and cleans 
        // them up on destruction. User need not worry about memory cleanup of 
        // the error_info objects.

           error_info_list reasons_eil;
           einf->reasons(reasons_eil);
           const error_info* reason_einf = NULL;
           for (reasons_eil.init(); NULL != (reason_einf = reasons_eil.next());)
           {
               display_problems_encountered(reason_einf);
           }
    } 
}

 
// Code demonstrating coincident cluster reporting by api_stitch and api_stitch_nonmanifold
// Get the number of coincident faces clusters

int num_clusters = sopts.get_number_of_coincident_face_clusters();

// Check if coincident faces were detected

if ( num_clusters > 0 )
{
 // Allocate memory based on the size of coincident face cluster list

    coin_face_list = ACIS_NEW ENTITY_LIST[num_clusters];

 // Now to go in a loop to collect each coincident face cluster

    ENTITY_LIST* cluster = NULL;
    int cluster_index = 0;
    sopts.init_coincident_face_cluster_list();
    while (NULL != (cluster = sopts.get_next_coincident_face_cluster()))
    {
        coin_face_list[cluster_index] = *cluster; // deep copy list
        cluster_index ++ ;
    }

 // Process each cluster (as an example, just print the
 // size of each cluster). In practice, customers will probably
 // want to exit to a handling routine which deletes items from the
 // to_be_stitched list and recalls this routine.

    int i=0;
    for (i = 0; i < num_clusters; i++)
    {
        int num_faces = coin_face_list[i].count();
        printf("Number of faces in cluster %d = %d", i, num_faces);
    }

 // Delete the coincident faces cluster list.

    if ( coin_face_list != NULL )
    {
        ACIS_DELETE [] coin_face_list;
        coin_face_list = NULL;
    } 
} // end braces for "num_clusters > 0"

 
// Utility function for displaying entity_error_info based problems encountered by api_stitch and api_stitch_nonmanifold
 
void display_problems_encountered(const error_info *einf)
{
    if ( NULL == einf )
    { return; }
    char const *err_message = einf->error_message();
    spa_outcome_severity_type err_severity = einf->severity();

 // User code to display message and severity
 // for example, the user might do the following

    printf("Problem encountered: %s\n", err_message);
    if (SPA_OUTCOME_FATAL == err_severity)

 // Represents a fatal error

    { printf("Severity: FATAL \n"); }
    else if (SPA_OUTCOME_ERROR == err_severity)

 // Represents an error encountered by a failsafe routine 
 // during an atomic operation

    { printf("Severity: ERROR \n"); }
    else if (SPA_OUTCOME_PROBLEM == err_severity)

 // Represents a problem encountered during an operation

    { printf("Severity: PROBLEM \n"); }
    else if (SPA_OUTCOME_INSANITY == err_severity)

 // Represents an insanity in the model

    { printf("Severity: INSANITY \n"); }

    int ent_id_cnt = get_error_info_entity_id_count(einf);

 // If ent_id_cnt returns positive count,
 // then einf has atleast one entity, dead or live

    if ( 0 < ent_id_cnt && einf->type() == entity_error_info::id() )
    {
        const entity_error_info* ent_einf = (const entity_error_info *)einf;
        if ( /* the user wants to report problems on dead entities too */ )

        // LIVE and DEAD entities

        {
            for (int i = 0; i < ent_id_cnt; i++)
            {
                tag_id_type ent_id = ent_einf->get_entity_id(i);
                ENTITY *err_entity = NULL;
                outcome res_get_ent = api_get_entity_from_id(ent_id, err_entity);

                if ( !res_get_ent.ok() )
                {
                    // Handle API failure and continue or exit as caller thinks suitable
                       ...
                }
                if (NULL != err_entity) // err_entity is LIVE
                {
                    // User code to report a live entity associated with a problem,
                    // for example the user may want to highlight the entity
                }
                else
                {
                    // Report problem for a dead entity
                }
            }
        }

        else // Only LIVE entities
        {
            ENTITY_LIST live_entities;
            ent_einf->get_entities_alive(live_entities);
            ENTITY *live_err_entity = NULL;
            for (live_entities.init(); NULL != (live_err_entity = live_entities.next()); )
            {
                // User code to report a live entity associated with a problem,
                // for example the user may want to highlight the entity
            }
        }
    }
} 

[Top]