/*********************************************************************** FONCTION : ---------- File OpenGl_togl_texture.c : REMARQUES: ---------- HISTORIQUE DES MODIFICATIONS : -------------------------------- 05-08-97 : PCT ; Support texture mapping ajout pour deuxieme passe du texture mapping ************************************************************************/ #define G003 /* EUG 16-09-99 ZBufferAuto treatment */ /*----------------------------------------------------------------------*/ /* * Includes */ #include #include #include #include #include #include #include #include #include static MtblPtr TsmMtblArray[TelLast]; /* Fixed Header info for a structure */ typedef struct TSM_HEAD_STRUCT { Tint num; /* number of elements present */ } TSM_HEAD, *tsm_head; /* A Structure having fixed header and array of elements */ typedef struct TSM_STRUCT_STRUCT { TSM_HEAD header; Tint alloc; /* number of elements that can be accomodated */ TSM_ELEM elem[1]; } TSM_STRUCT, *tsm_struct; /* A node containing an elem when structure is in the form of a list */ typedef struct TSM_NODE_STRUCT { struct TSM_NODE_STRUCT *next; struct TSM_NODE_STRUCT *prev; TSM_ELEM elem; } TSM_NODE, *tsm_node; /* The head of the list when the structure is in the form of a list */ typedef struct TSM_LHEAD_STRUCT { tsm_node next; tsm_node prev; TSM_HEAD header; } TSM_LHEAD, *tsm_lhead; #define TsmStructureNotOpen -1 #define TsmInvalidStructure -1 /* Context maintained for the currently open structure */ typedef struct TSM_CONTEXT_STRUCT { Tint stid; /* Current Open Structure */ Tint ind; /* Current Element Index */ /* = TsmStructureNotOpen if no structure currently open */ tsm_struct s; /* Current Structure Pointer */ TSM_LHEAD l; /* Current Structure List Head */ tsm_node n; /* Current Element list node */ } TSM_CONTEXT, *tsm_context; static TSM_CONTEXT context = { TsmInvalidStructure, TsmStructureNotOpen }; static TEditMode edit_mode; #define TSM_HTBL_SIZE 251 static cmn_stg_tbl node_tbl; /* Table for list nodes containing elements */ static cmn_htbl stid_tbl; /* Hash table for Stid Vs Structure ptr */ /* Global workstation variable */ Tint TglActiveWs; /* valid only during traversals */ void TsmInitAllClasses( MtblPtr (**tbl)(TelType*), Tint size ) { register Tint i; TelType el; register MtblPtr fp; for( i=0; iheader.num; i++ ) { node = cmn_stg_tbl_get( node_tbl ); if( !node ) return TFailure; node->elem = s->elem[i]; node->next = prev->next; node->prev = prev; prev->next = node; node->next->prev = node; prev = node; } /* free structure memory */ /* deferred till close structure */ return TSuccess; } static tsm_struct TsmListToArray( void ) { Tint i, num; tsm_node node; tsm_struct s; tsm_lhead l; /* allocate structure memory using number of elements */ s = context.s, l = &context.l; if( !s || l->header.num > s->alloc ) { num = l->header.num; if( !num ) return 0; /* This is a valid return value and not an error */ if( s ) cmn_freemem( s ); s = context.s = cmn_getmem( 1, sizeof(TSM_ELEM) * num + offsetof( TSM_STRUCT, elem ), 1 ); if( !s ) return 0; /* modify hash table data entry for stid */ cmn_add_in_htbl( stid_tbl, context.stid, s ); s->alloc = num; } s->header = l->header; /* set structure header and element type and data by traversing the list */ for( i=0, node=l->next, num=s->header.num; inext ) { s->elem[i] = node->elem; } /* free list nodes and then list head */ /* deferred till next open structure call */ /* return structure pointer */ return s; } static void TsmFreeList( Tint sm_flag ) { tsm_node node, next; Tint num, i; num = context.l.header.num, next = context.l.next; for( i=0; ielem.el, Delete, node->elem.data, 0 ); next = node->next; cmn_stg_tbl_free( node ); } context.l.next = context.l.prev = context.n = (tsm_node)&context.l; return; } TStatus TsmOpenStructure( Tint stid ) { cmn_htbl_elem rec; tsm_struct s; if( context.ind != TsmStructureNotOpen ) return TFailure; /* Some structure already open */ if( !stid_tbl ) { stid_tbl = cmn_create_htbl( TSM_HTBL_SIZE ); if( !stid_tbl ) return TFailure; } if( !node_tbl ) { node_tbl = cmn_stg_tbl_create( 30, sizeof(TSM_NODE) ); if( !node_tbl ) return TFailure; } if( stid != context.stid ) TsmFreeList( 0 ); /* Look in hash table for stid */ rec = cmn_find_in_htbl( stid_tbl, stid, (void **)&s ); if( !rec ) { cmn_add_in_htbl( stid_tbl, stid, 0 ); context.stid = stid, context.ind = 0, context.s = 0, context.l.header.num = 0; } else { if( stid != context.stid ) { context.stid = stid, context.s = s; /* s might be null if structure is created and closed with num = 0 */ /* and then reopened */ if( s ) { TsmArrayToList( s ); context.ind = s->header.num, context.l.header = s->header; context.n = context.l.prev; } else { context.ind = 0; } } else /* reuse previous list */ { context.ind = context.l.header.num, context.n = context.l.prev, context.s = s; } } /* Ajout CAL, 14/09/95 */ /* on force l'update_state de toutes les wks a TNotDone */ TsmInitUpdateState (); return TSuccess; } TStatus TsmCloseStructure( void ) { if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ /* Convert list to array */ TsmListToArray(); context.ind = TsmStructureNotOpen; return TSuccess; } TStatus TsmDisplayStructure( Tint stid, Tint wsid ) { /* Tint i, num; */ /* cmn_htbl_elem rec; */ /* tsm_struct s; */ TSM_ELEM_DATA data; CMN_KEY key; TglActiveWs = wsid; if( context.ind != TsmStructureNotOpen ) return TFailure; /* Some structure currently open */ key.id = wsid; data.ldata = stid; TsmSendMessage( TelExecuteStructure, DisplayTraverse, data, 1, &key ); return TSuccess; } TStatus TsmPrintStructure( Tint stid ) { Tint i, num; cmn_htbl_elem rec; tsm_struct s; if( context.ind != TsmStructureNotOpen ) return TFailure; /* Some structure currently open */ if( !stid_tbl ) return TFailure; /* No structure created yet */ /* Obtain structure pointer from hash table */ rec = cmn_find_in_htbl( stid_tbl, stid, (void **)&s ); if( !rec ) return TFailure; /* Non-existent structure */ printf( "\nPRINT:" ); printf( "\n\tSTRUCTURE ID = %d", stid ); if( !s ) { num = 0; } else { num = s->header.num; } printf( "\n\tNUMBER OF ELEMENTS = %d", num); printf( "\n" ); /* For each element Send Message Print */ for( i = 0; i < num; i++ ) { printf("\n\tElement[%d] : ", i+1); TsmSendMessage( s->elem[i].el, Print, s->elem[i].data, 0 ); } return TSuccess; } TStatus TsmAddToStructure( TelType el, Tint n, ... ) { TSM_ELEM_DATA data; #if defined (SOLARIS) || defined (IRIXO32) cmn_key *k; #else cmn_key k[TMaxArgs]; #endif if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ CMN_GET_STACK( n, k ); data.pdata = &data; if( TsmSendMessage( el, Add, data, -n, k ) == TFailure ) return TFailure; if( edit_mode == TEditReplace ) { TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 ); } else { tsm_node node; node = cmn_stg_tbl_get( node_tbl ); if( !node ) return TFailure; /* insert the node in the linked list after the current node */ node->prev = context.n; node->next = context.n->next; context.n->next = node; node->next->prev = node; /* Make this node as current node */ context.n = node; context.ind++; /* Increment the no of elements */ context.l.header.num++; } context.n->elem.el = el; context.n->elem.data = data; return TSuccess; } TStatus TsmEmptyStructure( Tint stid ) { cmn_htbl_elem rec; tsm_struct s; if( !stid_tbl ) return TFailure; /* No structure created yet */ /* Look in hash table for stid */ rec = cmn_find_in_htbl( stid_tbl, stid, (void **)&s ); if( !rec ) return TFailure; /* Non-existent structure */ /* For each element send message DELETE element */ if( context.ind != TsmStructureNotOpen && context.stid == stid ) { TsmFreeList( 1 ); context.l.header.num = 0; context.ind = 0; } else if( s ) s->header.num = 0; return TSuccess; } TStatus TsmDeleteStructure( Tint stid ) { Tint i, num; cmn_htbl_elem rec; tsm_struct s; if( context.ind != TsmStructureNotOpen && context.stid == stid ) return TFailure; /* Same structure currently open */ if( !stid_tbl ) return TFailure; /* No structure created yet */ rec = cmn_find_in_htbl( stid_tbl, stid, (void **)&s ); if( !rec ) return TFailure; /* Non-existent structure */ if( stid == context.stid ) /* Ensure that the list is freed on subsequent OpenStruct call */ /* even when same structure id is reused */ context.stid = TsmInvalidStructure; if( s ) { num = s->header.num; /* For each element send message DELETE element */ for( i=0; ielem[i].el, Delete, s->elem[i].data, 0 ); } /* Free structure memory */ cmn_freemem( s ); } /* Remove hash table entry */ cmn_delete_from_htbl( stid_tbl, stid, (void **)&s ); /* Ajout BGN, 27/05/97 */ /* on force l'update_state de toutes les wks a TNotDone */ TsmInitUpdateState (); return TSuccess; } TEditMode TsmSetEditMode( TEditMode mode ) { TEditMode m; m = edit_mode; /* Set static variable for mode */ edit_mode = mode; /* return previous mode */ return m; } TStatus TsmDeleteElement( void ) { tsm_node node; if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ if( !context.ind ) return TFailure; /* Send message DELETE element */ TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 ); node = context.n; node->prev->next = node->next; node->next->prev = node->prev; /* make previous node as current node */ context.n = node->prev; context.ind--; /* Decrement the no of elements */ context.l.header.num--; /* free the linked list node */ cmn_stg_tbl_free( node ); return TSuccess; } TStatus TsmDeleteElementsBetweenLabels( Tint label_id1, Tint label_id2 ) /* label_id1 & label_id2 exclusive */ { Tint elem1, elem2; if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ TsmSetElementPointer( 0 ); if( TsmSetElementPointerAtLabel( label_id1 ) == TFailure) return TFailure; elem1 = context.ind; if( TsmSetElementPointerAtLabel( label_id2 ) == TFailure) return TFailure; elem2 = context.ind; TsmDeleteElementRange( elem1, elem2 ); return TSuccess; } TStatus TsmDeleteElementRange( Tint elem1, Tint elem2 ) /* elem1 & elem2 exclusive */ { if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ TsmSetElementPointer( elem2 - 1 ); while( context.ind != elem1 && context.ind ) TsmDeleteElement(); return TSuccess; } TStatus TsmSetElementPointer( Tint index ) { if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ /* Set static variable accordingly */ if( context.ind == index ) { return TSuccess; } if( index > context.l.header.num ) { index = context.l.header.num; context.n = context.l.prev; } else if( !index ) { context.n = (tsm_node)&context.l; } else if( index < 0 ) { index = 0; context.n = (tsm_node)&context.l; } else { Tint a, b, c, d; tsm_node node; a = index - 0; b = context.ind - index; if( b < 0 ) b = -b; /* b = labs(b) */ c = context.l.header.num - index; d = ( a < b ) ? ( a < c ? a : c ) : ( b < c ? b : c ) ; if( a == d ) { /* Traverse from head in forward direction */ d = index-1; node = context.l.next; while( d-- ) { node = node->next; } } else if( b == d ) { /* Traverse from current node in appropriate direction */ node = context.n; d = context.ind; if( context.ind < index ) { while( d != index ) { node = node->next; d++; } } else { while( d != index ) { node = node->prev; d--; } } } else /* ( c == d ) */ { /* Traverse from head in backward direction */ d = context.l.header.num; node = context.l.prev; while( d != index ) { node = node->prev; d--; } } context.n = node; } context.ind = index; return TSuccess; } TStatus TsmSetElementPointerAtLabel( Tint label_id ) { Tint i, num; tsm_node node; if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ num = context.l.header.num; for( i=context.ind+1, node=context.n->next; i<=num; i++, node=node->next ) { if( node->elem.el == TelLabel && node->elem.data.ldata == label_id ) { context.ind = i; context.n = node; return TSuccess; } } return TFailure; } TStatus TsmSetElementPointerAtPickId( Tint pick_id ) { Tint i, num; tsm_node node; if( context.ind == TsmStructureNotOpen ) return TFailure; /* No structure currently open */ num = context.l.header.num; for( i=context.ind+1, node=context.n->next; i<=num; i++, node=node->next ) { if( node->elem.el == TelPickId && node->elem.data.ldata == pick_id ) { context.ind = i; context.n = node; break; } } return TSuccess; } TStatus TsmOffsetElementPointer( Tint offset ) { return TsmSetElementPointer( context.ind + offset ); } TStatus TsmPickStructure( Tint stid ) { Tint i, num; cmn_htbl_elem rec; tsm_struct s; if( context.ind != TsmStructureNotOpen ) return TFailure; /* Some structure currently open */ if( !stid_tbl ) return TFailure; /* No structure created yet */ /* Obtain structure pointer from hash table */ rec = cmn_find_in_htbl( stid_tbl, stid, (void**)&s ); if( !rec ) return TFailure; /* Non-existent structure */ /* For each element Send Message PickTraverse */ num = s->header.num; for( i = 0; i < num; i++ ) { TsmSendMessage( s->elem[i].el, PickTraverse, s->elem[i].data, 0 ); } return TSuccess; } TStatus TsmGetStructure( Tint stid, Tint *num, tsm_elem *e ) { cmn_htbl_elem rec; tsm_struct s; if( !stid_tbl ) return TFailure; /* No structure created yet */ /* Obtain structure pointer from hash table */ rec = cmn_find_in_htbl( stid_tbl, stid, (void **)&s ); if( !rec ) return TFailure; /* Non-existent structure */ *num = 0; if( s ) *num = s->header.num; *e = s->elem; return TSuccess; } static TStatus GetDepth( Tint stid, Tint *depth ) { cmn_htbl_elem rec; tsm_struct s; Tint i, d, b; tsm_elem e; if( !stid_tbl ) return TFailure; /* No structure created yet */ /* Obtain structure pointer from hash table */ rec = cmn_find_in_htbl( stid_tbl, stid, (void **)&s ); if( !rec ) return TFailure; /* Non-existent structure */ (*depth)++; d = b = *depth; if( s ) { e = s->elem; for( i = 0; i < s->header.num; i++ ) { if( e[i].el == TelExecuteStructure ) { GetDepth( e[i].data.ldata, &d ); if( *depth < d ) *depth = d; } d = b; } } return TSuccess; } TStatus TsmGetStructureDepth( Tint stid, Tint *depth ) { *depth = 0; GetDepth( stid, depth ); return TSuccess; } TStatus TsmGetCurElem( TSM_ELEM *elem ) { if( context.ind == TsmStructureNotOpen ) return TFailure; *elem = context.n->elem; return TSuccess; } TStatus TsmGetCurElemPtr( Tint *ptr ) { if( context.ind == TsmStructureNotOpen ) return TFailure; *ptr = context.ind; return TSuccess; }