/***************************************************************************** udo_occ_sample_application.c ========================================================================= Copyright (c) 2004 UGS PLM Solutions and EDS Company Unpublished - All rights reserved ========================================================================= File Description This c file in addition to udo_occ_sample_udo.c, udo_occ_sample_startup.men, and udo_occ_sample_application.men adds an Application to the UG Menubar. The applications create an occurrenceable or a non occurrenceable UDO on the face of a block that is displayed as a circle with a center point, and the class name (UDO_OCC_SAMPLE or UDO_NON_OCC_SAMPLE) displayed next to the center point. The UDO classes are defined/created in udo_occ_sample_udo.c. udo_occ_sample_startup.men defines the new applications that get added to the Application pulldown menu. udo_occ_sample_application.men defines the new pulldown menu from the UG Menubar that is only present after selecting the new application from the Application pulldown. The new pulldown menu is titled "UDO Occ Sample Applications" and the functions that hook up to the items in the UDO Applications pulldown menu are defined in this file. Please see the uf_udobj chapter of the Open API Reference Guide for a detailed description of this example, the required MenuScript environment variables and directories, and the correct placement of the shared library and menu files. Additional information on MenuScript can be found in: - the UG/Open MenuScript User Guide - the UG/Open API Reference Manual - the UG/Open API Programmer's Manual - the UG/Open MenuScript Quick Reference Card - the UG/Open MenuScript Menu File Reference Card *** PLEASE NOTE *** The shared library created from this program must be placed in the application directory specified by the UGII_SITE_DIR or the UGII_USER_DIR environment variable (i.e. the shared library must not be in the startup directory). ========================================================================= */ /* Include files */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* The class id's for associating UDO's with two perpendicular/adjacent edges */ static unsigned int UDO_occ_sample_class; static unsigned int UDO_non_occ_sample_class; /* structure used to hold the data that defines the placement of the circle */ typedef struct edge_data_s{ tag_t horiz_edge; /* linear edge selected by the user */ double horiz_point1[3]; /* end point of the horiz_edge, this should be the same point as vert_point1*/ double horiz_point2[3]; /* other end point of the horiz_edge */ tag_t vert_edge; /* linear edge selected by the user, must be adjacent and perpendicular to the horiz_edge */ double vert_point1[3]; /* end point of the vert_edge, this should be the same point as horiz_point1 */ double vert_point2[3]; /* other end point of the vert_edge */ }edge_data_t,*edge_data_p_t; /******************************************************************** * select_edges * * DESCRIPTION * Calls the dialog that prompts the user to select two * perpendicular/adjacent linear edges, and then fills in * the edge_data structure to reflect the selections * * INPUT * data * Non-null pointer to a data structure of type edge_data_t * OUTPUT * data * horiz_edge * The first edge the user selected (must be linear). * horiz_point1 * The common endpoint of both horiz_edge and vert_edge. * horiz_point2 * The other endpoint of the horiz_edge. * vert_edge * The second edge selected by the user (must be linear, * and adjacent/perpendicular to horiz_edge ) * vert_edge1 * The common endpoint of both horiz_edge and vert_edge. * vert_edge2 * The other endpoint of vert_edge. * * RETURNS * 1 - The user canceled out of the selection dialog * 0 - The user has successfully selected the data necessary * to create the UDO. ********************************************************************/ static int select_edges( edge_data_p_t data ); /******************************************************************** * init_proc * * DESCRIPTION * Initializes the mask that determines what is selectable. * This function is used as input for UF_UI_select_with_single_dialog * ********************************************************************/ static int init_proc( UF_UI_selection_p_t select, void *user_data); /******************************************************************** * validate_sel_edge * * DESCRIPTION * Compares the selected object with the horizontal edge in the * edge data structure. If the selected object is both adjacent * and perpendicular to the horizontal edge, then fill in the * rest of the edge data structure and return UF_UI_SEL_ACCEPT. * Otherwise, pop up a dialog with an explanation of why the * selected object is invalid, and return UF_UI_SEL_REJECT. * * INPUT * object * Tag of a linear edge selected by the user. * data * Edge data containing the following: * horiz_edge * The first edge selected by the user * horiz_point1 * One of the endpoints of the horiz_edge. * horiz_point2 * The other endpoint of the horiz_edge. * * OUTPUT * data * Edge data containing the following: * horiz_edge * The first edge selected by the user * horiz_point1 * The endpoint that is common to both horiz_edge and vert_edge. * horiz_point2 * The other endpoint of the horiz_edge. * vert_edge * The selected object (If it was valid, otherwise it remains unchanged) * vert_point1 * The endpoint that is common to both horiz_edge and vert_edge. * vert_point2 * The other endpoint of vert_edge. * * RETURNS * UF_UI_SEL_ACCEPT * The selected object was perpendicular and adjacent to the * horizontal edge in the edge data structure. * UF_UI_SEL_REJECT * The selected object was not perpendicular or adjacent to the * horizontal edge in the edge data structure. ********************************************************************/ static int validate_sel_edge( tag_t object, edge_data_p_t data ); /******************************************************************** * find_common_point * * DESCRIPTION * Given the edge data, check to see if the two edges have a * common endpoint. If the two edges have a common * endpoint, return TRUE and set horiz_point1 and vert_point1 * to the common endpoint. Set horiz_point2 to the other * endpoint of the horizontal edge, and vert_point2 to the * other endpoint of the vertical edge. * * INPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * One of the endpoints of the horizontal edge. * horiz_point2 * The other endpoint of the horizontal edge. * vert_edge * The potential adjacent linear edge to the horizontal edge. * vert_point1 * One of the endpoints of the vertical edge. * vert_point2 * The other endpoint of the vertical edge. * * OUTPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * The common endpoint, if one exists, of the horizontal * and vertical edges, otherwise this is unchanged. * horiz_point2 * The other endpoint of the horizontal edge. * vert_edge * The potential adjacent linear edge to the horizontal edge. * vert_point1 * The common endpoint, if one exists, of the horizontal * and vertical edges, otherwise this is unchanged. * vert_point2 * The other endpoint of the vertical edge. * * RETURNS * TRUE - There was a common endpoint. * FALSE - The edges do not have a common endpoint. ********************************************************************/ static logical find_common_point( edge_data_p_t data ); /******************************************************************** * swap_edge_data_points * * DESCRIPTION * Given the edge data, if swap_horiz_pts is true, swap * the two horizontal points, and if swap_vert_pts is true, * swap the two vertical points. * * INPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * One of the endpoints of the horizontal edge. * horiz_point2 * The other endpoint of the horizontal edge. * vert_edge * The vertical linear edge. * vert_point1 * One of the endpoints of the vertical edge. * vert_point2 * The other endpoint of the vertical edge. * * OUTPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * If swap_horiz_pts was true, then (input)horiz_point2 * otherwise this variable is unchanged. * horiz_point2 * If swap_horiz_pts was true, then (input)horiz_point1 * otherwise this variable is unchanged. * vert_edge * The vertical linear edge. * vert_point1 * If swap_vert_pts was true, then (input)horiz_point2 * otherwise this variable is unchanged. * vert_point2 * If swap_vert_pts was true, then (input)horiz_point1 * otherwise this variable is unchanged. * ********************************************************************/ static void swap_edge_data_points( edge_data_p_t data, logical swap_horiz_pts, logical swap_vert_pts ); /*----------------------------------------------------------------------------* * UDO_OCC_SAMPLE_APPLICATION__enter * * Enter the application *----------------------------------------------------------------------------*/ static void UDO_OCC_SAMPLE_APPLICATION__enter( void ); /*----------------------------------------------------------------------------* * UDO_OCC_SAMPLE_APPLICATION__init * * Initialize the application *----------------------------------------------------------------------------*/ static void UDO_OCC_SAMPLE_APPLICATION__init( void ); /*----------------------------------------------------------------------------* * UDO_OCC_SAMPLE_APPLICATION__exit * * Exit the application *----------------------------------------------------------------------------*/ static void UDO_OCC_SAMPLE_APPLICATION__exit( void ); /******************************************************************** * UDO_OCC_SAMPLE_APPLICATION__create_occ_udo * * DESCRIPTION * This function is activated by selecting Create Occurrenceable * UDO from the UDO Applications pulldown menu. * Creates an instance of the UDO Occ Sample class. *******************************************************************/ static UF_MB_cb_status_t UDO_OCC_SAMPLE_APPLICATION__create_occ_udo( UF_MB_widget_t widget, UF_MB_data_t client_data, UF_MB_activated_button_p_t call_button ); /******************************************************************** * UDO_OCC_SAMPLE_APPLICATION__create_non_occ_udo * * DESCRIPTION * This function is activated by selecting Create Non-Occurrenceable * UDO from the UDO Applications pulldown menu. * Creates an instance of the UDO Non Occ Sample class. *******************************************************************/ static UF_MB_cb_status_t UDO_OCC_SAMPLE_APPLICATION__create_non_occ_udo( UF_MB_widget_t widget, UF_MB_data_t client_data, UF_MB_activated_button_p_t call_button ); static int app_id = 0; static UF_MB_action_t actionTable[] = { { "UDO_OCC_SAMPLE_APPLICATION__create_occ_udo", UDO_OCC_SAMPLE_APPLICATION__create_occ_udo, &app_id }, { "UDO_OCC_SAMPLE_APPLICATION__create_non_occ_udo", UDO_OCC_SAMPLE_APPLICATION__create_non_occ_udo, &app_id }, { NULL, NULL, NULL } }; /* UF_CALL is the standard User Function error handling mechanism that is recommended to anyone calling a user function */ #define UF_CALL(X)(report_error( __FILE__, __LINE__, #X, (X))) /* report_error works in conjunction with the UF_CALL macro */ static int report_error( char *file, int line, char *call, int irc ) { if(irc) { char err[133], msg[133]; sprintf( msg, "*** ERROR code %d at line %d in %s:\n+++", irc, line, file ); UF_get_fail_message( irc, err ); UF_print_syslog( msg, FALSE ); UF_print_syslog( err, FALSE ); UF_print_syslog( "\n", FALSE ); UF_print_syslog( call, FALSE ); UF_print_syslog( ";\n", FALSE ); if( !UF_UI_open_listing_window() ) { UF_UI_write_listing_window( msg ); UF_UI_write_listing_window( err ); UF_UI_write_listing_window( "\n" ); UF_UI_write_listing_window( call ); UF_UI_write_listing_window( ";\n" ); } } return( irc ); } /******************************************************************** * UDO_OCC_SAMPLE_APPLICATION__create_occ_udo * * DESCRIPTION * This function is activated by selecting Create Occurrenceable * UDO from the UDO Applications pulldown menu. * Creates an instance of the UDO Occ Sample class. *******************************************************************/ static UF_MB_cb_status_t UDO_OCC_SAMPLE_APPLICATION__create_occ_udo( UF_MB_widget_t widget, UF_MB_data_t client_data, UF_MB_activated_button_p_t call_button ) { /* Initialize the API environment */ if( !UF_CALL( UF_initialize() )); { int done = 0; edge_data_t data; tag_t udo_tag = NULL_TAG; int error = 0; UF_UDOBJ_link_p_t link_defs = NULL; UF_CALL( UF_UDOBJ_ask_class_id_of_name( "udo_occ_sample", &UDO_occ_sample_class )); while (!done) { data.horiz_edge = NULL_TAG; data.vert_edge = NULL_TAG; done = select_edges( &data ); if( done == 0 ) { link_defs = UF_allocate_memory( sizeof(UF_UDOBJ_link_t)*2, &error ); UF_CALL( UF_UDOBJ_create_udo( UDO_occ_sample_class, &udo_tag ) ); if( !error ) { link_defs[0].assoc_ug_tag = data.horiz_edge; link_defs[0].link_type = 1; link_defs[0].object_status = 0; link_defs[1].assoc_ug_tag = data.vert_edge; link_defs[1].link_type = 1; link_defs[1].object_status = 0; UF_CALL( UF_UDOBJ_add_links ( udo_tag, 2, link_defs )); UF_CALL( UF_DISP_add_item_to_display( udo_tag )); } else { char err_msg[133]; UF_get_fail_message( error, err_msg ); UF_print_syslog( err_msg, FALSE ); } } } /* Terminate the API environment */ UF_CALL( UF_terminate() ); } return( UF_MB_CB_CONTINUE ); } /******************************************************************** * UDO_OCC_SAMPLE_APPLICATION__create_non_occ_udo * * DESCRIPTION * This function is activated by selecting Create Non-Occurrenceable * UDO from the UDO Applications pulldown menu. * Creates an instance of the UDO Non Occ Sample class. *******************************************************************/ static UF_MB_cb_status_t UDO_OCC_SAMPLE_APPLICATION__create_non_occ_udo( UF_MB_widget_t widget, UF_MB_data_t client_data, UF_MB_activated_button_p_t call_button ) { /* Initialize the API environment */ if( !UF_CALL( UF_initialize() )); { int done = 0; edge_data_t data; tag_t udo_tag = NULL_TAG; int error = 0; UF_UDOBJ_link_p_t link_defs = NULL; UF_CALL( UF_UDOBJ_ask_class_id_of_name( "udo_non_occ_sample", &UDO_non_occ_sample_class )); while (!done) { data.horiz_edge = NULL_TAG; data.vert_edge = NULL_TAG; done = select_edges( &data ); if( done == 0 ) { link_defs = UF_allocate_memory( sizeof(UF_UDOBJ_link_t)*2, &error ); UF_CALL( UF_UDOBJ_create_udo( UDO_non_occ_sample_class, &udo_tag ) ); if( !error ) { link_defs[0].assoc_ug_tag = data.horiz_edge; link_defs[0].link_type = 1; link_defs[0].object_status = 0; link_defs[1].assoc_ug_tag = data.vert_edge; link_defs[1].link_type = 1; link_defs[1].object_status = 0; UF_CALL( UF_UDOBJ_add_links ( udo_tag, 2, link_defs )); UF_CALL( UF_DISP_add_item_to_display( udo_tag )); } else { char err_msg[133]; UF_get_fail_message( error, err_msg ); UF_print_syslog( err_msg, FALSE ); } } } /* Terminate the API environment */ UF_CALL( UF_terminate() ); } return( UF_MB_CB_CONTINUE ); } /*----------------------------------------------------------------------------* * UDO_OCC_SAMPLE_APPLICATION__enter * * Enter the application *----------------------------------------------------------------------------*/ static void UDO_OCC_SAMPLE_APPLICATION__enter( void) { printf( "Entering UDO Circle application\n" ); /* Place code to enter application here */ } /*----------------------------------------------------------------------------* * UDO_OCC_SAMPLE_APPLICATION__init * * Initialize the application *----------------------------------------------------------------------------*/ static void UDO_OCC_SAMPLE_APPLICATION__init( void ) { printf( "Initializing UDO Circle application\n" ); /* Place code to initialize application here */ } /*----------------------------------------------------------------------------* * UDO_OCC_SAMPLE_APPLICATION__exit * * Exit the application *----------------------------------------------------------------------------*/ static void UDO_OCC_SAMPLE_APPLICATION__exit( void ) { printf( "Exiting UDO Circle application\n" ); /* Place code to cleanup for application and exit here */ } /*----------------------------------------------------------------------------* * PUBLIC void ufsta * * Register the application * *----------------------------------------------------------------------------*/ /* ARGSUSED */ extern void ufsta( char *param, int *retcod, int param_len ) { UF_MB_application_t appData; char name[] = "UDO_OCC_SAMPLE_APPLICATION"; int status; int ifail = 0; /* Initialize the API environment */ UF_CALL( UF_initialize() ); /* application setup */ UF_CALL( UF_MB_add_actions( actionTable )); appData.name = name; appData.id = 0; appData.init_proc = UDO_OCC_SAMPLE_APPLICATION__init; appData.exit_proc = UDO_OCC_SAMPLE_APPLICATION__exit; appData.enter_proc = UDO_OCC_SAMPLE_APPLICATION__enter; /* Initialize application support flags */ appData.drawings_supported = TRUE; appData.design_in_context_supported = TRUE; /* Register the application with UG */ UF_CALL( UF_MB_register_application( &appData )); app_id = appData.id; UF_CALL( UF_terminate() ); } /******************************************************************** * select_edges * * DESCRIPTION * Calls the dialog that prompts the user to select two * perpendicular/adjacent linear edges, and then fills in * the edge_data structure to reflect the selections * * INPUT * data * Non-null pointer to a data structure of type edge_data_t * OUTPUT * data * horiz_edge * The first edge the user selected (must be linear). * horiz_point1 * The common endpoint of both horiz_edge and vert_edge. * horiz_point2 * The other endpoint of the horiz_edge. * vert_edge * The second edge selected by the user (must be linear, * and adjacent/perpendicular to horiz_edge ) * vert_edge1 * The common endpoint of both horiz_edge and vert_edge. * vert_edge2 * The other endpoint of vert_edge. * * RETURNS * 1 - The user canceled out of the selection dialog * 0 - The user has successfully selected the data necessary * to create the UDO. ********************************************************************/ static int select_edges( edge_data_p_t data ) { char horiz_cue[] = "Select a Horizontal Edge"; char vert_cue[] = "Select a Vertical Edge"; char title[] = "Select Adjacent Edges of a Block"; int response = 0; int object_count = 0; tag_t *objects = NULL; tag_t object = NULL_TAG; tag_t view = NULL_TAG; double cursor[3] = {0.0, 0.0, 0.0}; logical done = FALSE; int vertex_count = 0; data->horiz_edge = NULL_TAG; data->vert_edge = NULL_TAG; /* prompt user for the first linear edge */ if(!UF_CALL( UF_UI_select_with_single_dialog(horiz_cue,title, UF_UI_SEL_SCOPE_NO_CHANGE, init_proc, data, &response, &object, cursor, &view))) { if (response == UF_UI_OBJECT_SELECTED || response == UF_UI_OBJECT_SELECTED_BY_NAME) { /* a valid selection has been made, initialize the edge data struct */ data->horiz_edge = object; UF_CALL( UF_MODL_ask_edge_verts( object, data->horiz_point1, data->horiz_point2, &vertex_count ) ); } else { /* The user canceled out of the selection dialog */ return 1; } } while( !done ) { /* prompt user for the second linear edge */ if(!UF_CALL(UF_UI_select_with_single_dialog(vert_cue,title, UF_UI_SEL_SCOPE_NO_CHANGE, init_proc, data, &response, &object, cursor, &view))) { if (response == UF_UI_OBJECT_SELECTED || response == UF_UI_OBJECT_SELECTED_BY_NAME) { /* an edge was selected, verify that it is adjacent/perpendicular to the first edge */ if( validate_sel_edge( object, data ) == UF_UI_SEL_ACCEPT ) { /* the selected edge was valid */ done = TRUE; } } else { /* The user canceled out of the selection dialog */ done = TRUE; return 1; } /* unhighlight last selected object */ UF_DISP_set_highlight(object,0); } } /* unhighlight first selected object */ UF_DISP_set_highlight(data->horiz_edge,0); return 0; } /******************************************************************** * init_proc * * DESCRIPTION * Initializes the mask that determines what is selectable. * This function is used as input for UF_UI_select_with_single_dialog * ********************************************************************/ static int init_proc( UF_UI_selection_p_t select, void* user_data) { int num_triples = 1; UF_UI_mask_t mask_triples[] = { UF_solid_type, 0, UF_UI_SEL_FEATURE_LINEAR_EDGE}; /* enable only linear edges */ if((UF_CALL(UF_UI_set_sel_mask(select, UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC, num_triples, mask_triples))) == 0) { return (UF_UI_SEL_SUCCESS); } else { return (UF_UI_SEL_FAILURE); } } /******************************************************************** * validate_sel_edge * * DESCRIPTION * Compares the selected object with the horizontal edge in the * edge data structure. If the selected object is both adjacent * and perpendicular to the horizontal edge, then fill in the * rest of the edge data structure and return UF_UI_SEL_ACCEPT. * Otherwise, pop up a dialog with an explanation of why the * selected object is invalid, and return UF_UI_SEL_REJECT. * * INPUT * object * Tag of a linear edge selected by the user. * data * Edge data containing the following: * horiz_edge * The first edge selected by the user * horiz_point1 * One of the endpoints of the horiz_edge. * horiz_point2 * The other endpoint of the horiz_edge. * * OUTPUT * data * Edge data containing the following: * horiz_edge * The first edge selected by the user * horiz_point1 * The endpoint that is common to both horiz_edge and vert_edge. * horiz_point2 * The other endpoint of the horiz_edge. * vert_edge * The selected object (If it was valid, otherwise it remains unchanged) * vert_point1 * The endpoint that is common to both horiz_edge and vert_edge. * vert_point2 * The other endpoint of vert_edge. * * RETURNS * UF_UI_SEL_ACCEPT * The selected object was perpendicular and adjacent to the * horizontal edge in the edge data structure. * UF_UI_SEL_REJECT * The selected object was not perpendicular or adjacent to the * horizontal edge in the edge data structure. ********************************************************************/ static int validate_sel_edge( tag_t object, edge_data_p_t data ) { double point1[3] = {0.0, 0.0, 0.0}; double point2[3] = {0.0, 0.0, 0.0}; int vertex_count = 0; int equal = 0; double tol = 0.000001; int response = 0; char *perpendicular_msgs[4] = { "The selected edge was not perpendicular", "to the Horizontal Edge.", "Please select an edge that is both perpedicular", "and adjacent to the selected Horizontal Edge."}; char *adjacent_msgs[4]= { "The selected edge is not adjacent", "to the Horizontal Edge.", "Please select an edge that is both perpendicular", "and adjacent to the selected Horizontal Edge."}; /* Find the endpoints of the selected object */ UF_CALL( UF_MODL_ask_edge_verts( object, data->vert_point1, data->vert_point2, &vertex_count ) ); /* Is the selected object Adjacent to the Horizontal edge? Check to see if the selected object had any points in common with the horizontal edge */ if( find_common_point( data ) ) { double horiz_vec[3] = {0.0, 0.0, 0.0}; double vert_vec[3] = {0.0, 0.0, 0.0}; int perpendicular = 0; UF_VEC3_sub( data->horiz_point2, data->horiz_point1, horiz_vec ); UF_VEC3_sub( data->vert_point2, data->vert_point1, vert_vec ); UF_VEC3_is_perpendicular( horiz_vec, vert_vec, tol, &perpendicular ); /* Is the selected object Perpendicular to the Horizontal edge? */ if( perpendicular ) { /* The selected edge is both adjacent and perpendicular to the horizontal edge */ data->vert_edge = object; return (UF_UI_SEL_ACCEPT); } /* this selected edge is not perpendicular to the horizontal edge */ UF_UI_message_dialog ( "Selection Error", UF_UI_MESSAGE_ERROR, perpendicular_msgs, 4, FALSE, NULL, &response ); return (UF_UI_SEL_REJECT); } /* this selected edge is not adjacent to the horizontal edge */ UF_UI_message_dialog ( "Selection Error", UF_UI_MESSAGE_ERROR, adjacent_msgs, 4, FALSE, NULL, &response ); return (UF_UI_SEL_REJECT); } /******************************************************************** * find_common_point * * DESCRIPTION * Given the edge data, check to see if the two edges have a * common endpoint. If the two edges have a common * endpoint, return TRUE and set horiz_point1 and vert_point1 * to the common endpoint. Set horiz_point2 to the other * endpoint of the horizontal edge, and vert_point2 to the * other endpoint of the vertical edge. * * INPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * One of the endpoints of the horizontal edge. * horiz_point2 * The other endpoint of the horizontal edge. * vert_edge * The potential adjacent linear edge to the horizontal edge. * vert_point1 * One of the endpoints of the vertical edge. * vert_point2 * The other endpoint of the vertical edge. * * OUTPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * The common endpoint, if one exists, of the horizontal * and vertical edges, otherwise this is unchanged. * horiz_point2 * The other endpoint of the horizontal edge. * vert_edge * The potential adjacent linear edge to the horizontal edge. * vert_point1 * The common endpoint, if one exists, of the horizontal * and vertical edges, otherwise this is unchanged. * vert_point2 * The other endpoint of the vertical edge. * * RETURNS * TRUE - There was a common endpoint. * FALSE - The edges do not have a common endpoint. ********************************************************************/ static logical find_common_point( edge_data_p_t data ) { double tol = 0.00001; double distance = 0.0; /* check the distance between the first horizontal endpoint and the first vertical endpoint. */ UF_VEC3_distance( data->horiz_point1, data->vert_point1, &distance ); if( distance > tol ) { /* now check the distance between the first horizontal endpoint and the second vertical endpoint */ UF_VEC3_distance( data->horiz_point1, data->vert_point2, &distance ); if( distance <= tol ) { /* If the first horizontal point is equal to the second vertical point, swap the two vertical endpoints. */ swap_edge_data_points( data, FALSE, TRUE ); } } if( distance > tol ) { /* now check the distance between the second horizontal endpoint and the first vertical endpoint */ UF_VEC3_distance( data->horiz_point2, data->vert_point1, &distance ); if( distance <= tol ) { /* If the first horizontal point is equal to the second vertical point, swap the two horizontal endpoints. */ swap_edge_data_points( data, TRUE, FALSE ); } } if( distance > tol ) { /* now check the distance between the second horizontal endpoint and the second vertical endpoint */ UF_VEC3_distance( data->horiz_point2, data->vert_point2, &distance ); if( distance <= tol ) { /* If the second horizontal point is equal to the second vertical point, swap the two horizontal endpoints and swap the two vertical endpoints. */ swap_edge_data_points( data, TRUE, TRUE ); } } if( distance <= tol ) { /* a common endpoint was found */ return( TRUE ); } /* there were no common endpoints */ return( FALSE ); } /******************************************************************** * swap_edge_data_points * * DESCRIPTION * Given the edge data, if swap_horiz_pts is true, swap * the two horizontal points, and if swap_vert_pts is true, * swap the two vertical points. * * INPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * One of the endpoints of the horizontal edge. * horiz_point2 * The other endpoint of the horizontal edge. * vert_edge * The vertical linear edge. * vert_point1 * One of the endpoints of the vertical edge. * vert_point2 * The other endpoint of the vertical edge. * * OUTPUT * data * horiz_edge * The horizontal linear edge. * horiz_point1 * If swap_horiz_pts was true, then (input)horiz_point2 * otherwise this variable is unchanged. * horiz_point2 * If swap_horiz_pts was true, then (input)horiz_point1 * otherwise this variable is unchanged. * vert_edge * The vertical linear edge. * vert_point1 * If swap_vert_pts was true, then (input)horiz_point2 * otherwise this variable is unchanged. * vert_point2 * If swap_vert_pts was true, then (input)horiz_point1 * otherwise this variable is unchanged. * ********************************************************************/ static void swap_edge_data_points( edge_data_p_t data, logical swap_horiz_pts, logical swap_vert_pts ) { double temp_point[3] = {0.0, 0.0, 0.0}; if( swap_horiz_pts ) { temp_point[0] = data->horiz_point1[0]; temp_point[1] = data->horiz_point1[1]; temp_point[2] = data->horiz_point1[2]; data->horiz_point1[0] = data->horiz_point2[0]; data->horiz_point1[1] = data->horiz_point2[1]; data->horiz_point1[2] = data->horiz_point2[2]; data->horiz_point2[0] = temp_point[0]; data->horiz_point2[1] = temp_point[1]; data->horiz_point2[2] = temp_point[2]; } if( swap_vert_pts ) { temp_point[0] = data->vert_point1[0]; temp_point[1] = data->vert_point1[1]; temp_point[2] = data->vert_point1[2]; data->vert_point1[0] = data->vert_point2[0]; data->vert_point1[1] = data->vert_point2[1]; data->vert_point1[2] = data->vert_point2[2]; data->vert_point2[0] = temp_point[0]; data->vert_point2[1] = temp_point[1]; data->vert_point2[2] = temp_point[2]; } } /***************************************************************************** ** Utilities *****************************************************************************/ /* Unload Handler ** This function specifies when to unload your application from Unigraphics. ** If your application registers a callback (from a MenuScript item or a ** User Defined Object for example), this function MUST return ** "UF_UNLOAD_UG_TERMINATE". */ extern int ufusr_ask_unload( void ) { return( UF_UNLOAD_UG_TERMINATE ); }