Home
>
User Guide >
Modeling Operations >
Intersectors, Booleans, and Stitching >
Stitching >
Tolerant Stitching
The following sample code demonstrates how to typically perform tolerant
stitching using
api_stitch and
api_stitch_nonmanifold. [Top] © 1989-2007 Spatial Corp., a Dassault Systèmes company. All
rights reserved.
Tolerant Stitching Sample Code
// 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
}
}
}
}