1 /***********************************************************************
5 File OpenGl_togl_texture.c :
12 HISTORIQUE DES MODIFICATIONS :
13 --------------------------------
14 05-08-97 : PCT ; Support texture mapping
15 ajout pour deuxieme passe du texture mapping
17 ************************************************************************/
19 #define G003 /* EUG 16-09-99 ZBufferAuto treatment
22 /*----------------------------------------------------------------------*/
27 #include <OpenGl_tgl_all.hxx>
32 #include <OpenGl_cmn_varargs.hxx>
33 #include <OpenGl_tsm.hxx>
34 #include <OpenGl_tsm_ws.hxx>
35 #include <OpenGl_Memory.hxx>
37 static MtblPtr TsmMtblArray[TelLast];
39 /* Fixed Header info for a structure */
40 struct TSM_HEAD_STRUCT
42 Tint num; /* number of elements present */
44 typedef TSM_HEAD_STRUCT TSM_HEAD;
45 typedef TSM_HEAD_STRUCT* tsm_head;
47 /* The head of the list when the structure is in the form of a list */
48 struct TSM_LHEAD_STRUCT
50 tsm_node next; // first list node
51 tsm_node prev; // last list node for reverse iteration
54 typedef TSM_LHEAD_STRUCT TSM_LHEAD;
55 typedef TSM_LHEAD_STRUCT *tsm_lhead;
57 /* A Structure having fixed header and variable list of elements */
58 struct TSM_STRUCT_STRUCT
60 TSM_LHEAD elemListHead;
61 IMPLEMENT_MEMORY_OPERATORS
63 typedef TSM_STRUCT_STRUCT TSM_STRUCT;
64 typedef TSM_STRUCT_STRUCT *tsm_struct;
66 #define TsmStructureNotOpen -1
67 #define TsmInvalidStructure -1
69 /* Context maintained for the currently open structure */
70 struct TSM_CONTEXT_STRUCT
72 Tint stid; /* Current Open Structure */
73 Tint ind; /* Current Element Index */
74 /* = TsmStructureNotOpen if no structure currently open */
75 tsm_struct s; /* Current Structure Pointer */
76 tsm_node n; /* Current Element list node */
78 typedef TSM_CONTEXT_STRUCT TSM_CONTEXT;
79 typedef TSM_CONTEXT_STRUCT* tsm_context;
81 static TSM_CONTEXT context = { TsmInvalidStructure, TsmStructureNotOpen, 0, 0 };
83 static TEditMode edit_mode;
85 #define TSM_HTBL_SIZE 251
86 typedef NCollection_List<TSM_NODE*> NodeList;
87 typedef NCollection_DataMap<Tint, TSM_STRUCT*> StructMap;
88 Handle(NCollection_BaseAllocator) _Allocator = NCollection_BaseAllocator::CommonBaseAllocator();
89 static StructMap _StructMap( 1, _Allocator );
93 /* Global workstation variable */
94 Tint TglActiveWs; /* valid only during traversals */
97 TsmInitAllClasses( MtblPtr (**tbl)(TelType*), Tint size )
103 for( i=0; i<size; i++ )
106 TsmMtblArray[el] = fp;
111 /* This function invokes the required method of the element type by looking
112 up an array of Method Tables of each element.
113 The arguments passed to the method are the data of the element and any
114 other data that needs to be sent.
115 In the case of ADD_TO_STRUCTURE methods, data should be the address of the
116 element data. Other wise, it is the element data itself
120 TsmSendMessage( TelType el, TMsgType msg, TSM_ELEM_DATA data, Tint n, ... )
122 #if defined (SOLARIS) || defined (IRIXO32)
127 // Nullifies 0-th element of the "k" array
128 // because it might be used in a UserDraw function
129 // to get information on view ID, for example.
131 // Uncomment the code below if you caught
132 // exception because of k[1] is NULL.
133 // Nullifies the whole array of "k"
139 TStatus TheStatus = TSuccess;
141 CMN_GET_STACK( n, k );
143 if( TsmMtblArray[el] && TsmMtblArray[el][msg] )
144 TheStatus = TsmMtblArray[el][msg]( data, n, k );
149 TsmFreeList( tsm_struct s )
154 if( _Allocator.IsNull() )
160 num = s->elemListHead.header.num;
161 node = s->elemListHead.next;
163 for( i=0; i<num; i++ )
165 TsmSendMessage( node->elem.el, Delete, node->elem.data, 0 );
171 s->elemListHead.next = s->elemListHead.prev = (tsm_node)&(s->elemListHead);
172 s->elemListHead.header.num = 0;
177 TsmOpenStructure( Tint stid )
181 if( _Allocator.IsNull() )
184 if( context.ind != TsmStructureNotOpen )
185 return TFailure; /* Some structure already open */
187 if ( !_StructMap.IsBound(stid) ){
188 s = new TSM_STRUCT();
190 return TFailure; // Memory allocation failed
192 _StructMap.Bind( stid, s );
193 s->elemListHead.next = s->elemListHead.prev = (tsm_node)&(s->elemListHead);
194 s->elemListHead.header.num = 0;
197 s = _StructMap.Find(stid);
201 // Make the context point at the last node of the structure,
202 // this is the list head in case of an empty structure
203 context.ind = s->elemListHead.header.num;
204 context.n = s->elemListHead.prev;
206 /* Ajout CAL, 14/09/95 */
207 /* on force l'update_state de toutes les wks a TNotDone */
208 TsmInitUpdateState ();
216 if( context.ind == TsmStructureNotOpen )
217 return TFailure; /* No structure currently open */
219 context.ind = TsmStructureNotOpen;
226 TsmDisplayStructure( Tint stid, Tint wsid )
233 if( context.ind != TsmStructureNotOpen )
234 return TFailure; /* Some structure currently open */
238 TsmSendMessage( TelExecuteStructure, DisplayTraverse, data, 1, &key );
244 TsmPrintStructure( Tint stid )
250 if( context.ind != TsmStructureNotOpen )
251 return TFailure; /* Some structure currently open */
253 if ( _StructMap.IsEmpty() )
254 return TFailure; /* No structure created yet */
256 /* Obtain structure pointer from hash table */
257 if ( !_StructMap.IsBound(stid) )
258 return TFailure; /* Non-existent structure */
260 s = _StructMap.Find(stid);
262 printf( "\nPRINT:" );
263 printf( "\n\tSTRUCTURE ID = %d", stid );
269 num = s->elemListHead.header.num;
270 node = s->elemListHead.next;
273 printf( "\n\tNUMBER OF ELEMENTS = %d", num);
276 /* For each element Send Message Print */
277 for( i = 0; i < num; i++ ){
278 printf("\n\tElement[%d] : ", i+1);
279 TsmSendMessage( node->elem.el, Print, node->elem.data, 0 );
287 TsmAddToStructure( TelType el, Tint n, ... )
290 #if defined (SOLARIS) || defined (IRIXO32)
296 if( context.ind == TsmStructureNotOpen )
297 return TFailure; /* No structure currently open */
299 CMN_GET_STACK( n, k );
301 if( TsmSendMessage( el, Add, data, -n, k ) == TFailure )
304 if( edit_mode == TEditReplace ){
305 TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 );
308 tsm_node node = new TSM_NODE();
313 /* insert the node in the linked list after the current node */
314 node->prev = context.n;
315 node->next = context.n->next;
316 context.n->next = node;
317 node->next->prev = node;
319 /* Make this node as current node */
323 /* Increment the no of elements */
324 context.s->elemListHead.header.num++;
327 context.n->elem.el = el;
328 context.n->elem.data = data;
334 TsmDeleteStructure( Tint stid )
336 if( context.ind != TsmStructureNotOpen && context.stid == stid )
337 return TFailure; /* Same structure currently open */
339 if ( _StructMap.IsEmpty() )
340 return TFailure; /* No structure created yet */
342 if ( !_StructMap.IsBound(stid) )
343 return TFailure; /* Non-existent structure */
345 tsm_struct s = _StructMap.ChangeFind(stid);
347 if( stid == context.stid ){
348 context.stid = TsmInvalidStructure;
349 // Ensure the context doesn't point to freed memory
357 /* Free structure memory */
361 /* Remove hash table entry */
362 _StructMap.UnBind( stid );
364 /* Ajout BGN, 27/05/97 */
365 /* on force l'update_state de toutes les wks a TNotDone */
366 TsmInitUpdateState ();
372 TsmSetEditMode( TEditMode mode )
378 /* Set static variable for mode */
381 /* return previous mode */
390 if( context.ind == TsmStructureNotOpen )
391 return TFailure; /* No structure currently open */
393 // Zero ind means the currently open structure is empty
394 // or the current node is the list head -> nothing to delete
395 // See also TsmSetElementPointer()
399 /* Send message DELETE element */
400 TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 );
403 node->prev->next = node->next;
404 node->next->prev = node->prev;
406 /* make previous node as current node */
407 context.n = node->prev;
410 /* Decrement the no of elements */
411 context.s->elemListHead.header.num--;
413 /* free the linked list node */
420 TsmDeleteElementsBetweenLabels( Tint label_id1, Tint label_id2 )
421 /* label_id1 & label_id2 exclusive */
425 if( context.ind == TsmStructureNotOpen )
426 return TFailure; /* No structure currently open */
428 TsmSetElementPointer( 0 );
430 if( TsmSetElementPointerAtLabel( label_id1 ) == TFailure)
434 if( TsmSetElementPointerAtLabel( label_id2 ) == TFailure)
438 TsmDeleteElementRange( elem1, elem2 );
444 TsmDeleteElementRange( Tint elem1, Tint elem2 ) /* elem1 & elem2 exclusive */
446 if( context.ind == TsmStructureNotOpen )
447 return TFailure; /* No structure currently open */
449 TsmSetElementPointer( elem2 - 1 );
450 while( context.ind != elem1 && context.ind )
457 TsmSetElementPointer( Tint index )
459 if( context.ind == TsmStructureNotOpen )
460 return TFailure; /* No structure currently open */
462 /* Set static variable accordingly */
463 if( context.ind == index ){
466 if( index >= context.s->elemListHead.header.num ){
467 index = context.s->elemListHead.header.num;
468 context.n = context.s->elemListHead.prev;
470 else if( index <= 0 ){
472 context.n = (tsm_node)&(context.s->elemListHead);
479 b = context.ind - index; if( b < 0 ) b = -b; /* b = labs(b) */
480 c = context.s->elemListHead.header.num - index;
481 d = ( a < b ) ? ( a < c ? a : c ) : ( b < c ? b : c ) ;
484 /* Traverse from head in forward direction */
486 node = context.s->elemListHead.next;
492 /* Traverse from current node in appropriate direction */
495 if( context.ind < index ){
508 else{ /* ( c == d ) */
509 /* Traverse from head in backward direction */
510 d = context.s->elemListHead.header.num;
511 node = context.s->elemListHead.prev;
528 TsmSetElementPointerAtLabel( Tint label_id )
533 if( context.ind == TsmStructureNotOpen )
534 return TFailure; /* No structure currently open */
536 num = context.s->elemListHead.header.num;
537 for( i=context.ind+1, node=context.n->next; i<=num; i++, node=node->next ){
538 if( node->elem.el == TelLabel && node->elem.data.ldata == label_id ){
549 TsmOffsetElementPointer( Tint offset )
551 return TsmSetElementPointer( context.ind + offset );
555 TsmGetStructure( Tint stid, Tint *num, tsm_node *n )
557 if ( _StructMap.IsEmpty() )
558 return TFailure; /* No structure created yet */
560 if ( !_StructMap.IsBound(stid) )
561 return TFailure; /* Non-existent structure */
563 tsm_struct s = _StructMap.Find(stid);
565 *num = s ? s->elemListHead.header.num : 0;
566 // Here we cannot return a pointer to the structure's list head,
567 // as it will wrongly interpreted as a regular pointer to TSM_NODE,
568 // thus returning null pointer - this should be checked by callers!
569 *n = s ? s->elemListHead.next : 0;
575 GetDepth( Tint stid, Tint *depth )
580 if ( _StructMap.IsEmpty() )
581 return TFailure; /* No structure created yet */
583 if ( !_StructMap.IsBound(stid) )
584 return TFailure; /* Non-existent structure */
586 s = _StructMap.Find(stid);
592 num = s->elemListHead.header.num;
593 tsm_node node = s->elemListHead.next;
594 for( i = 0; i < num; i++ ){
595 if( node->elem.el == TelExecuteStructure ){
596 GetDepth( node->elem.data.ldata, &d );
610 TsmGetStructureDepth( Tint stid, Tint *depth )
614 GetDepth( stid, depth );
619 TsmGetCurElem( TSM_ELEM *elem )
621 // Zero ind means no current element
622 if( context.ind == TsmStructureNotOpen ||
626 *elem = context.n->elem;
631 TsmGetCurElemPtr( Tint *ptr )
633 // Zero ind means no current element
634 if( context.ind == TsmStructureNotOpen ||