Integration of OCCT 6.5.0 from SVN
[occt.git] / src / OpenGl / OpenGl_tsm.cxx
CommitLineData
7fd59977 1/***********************************************************************
2
3FONCTION :
4----------
5File OpenGl_togl_texture.c :
6
7
8REMARQUES:
9----------
10
11
12HISTORIQUE DES MODIFICATIONS :
13--------------------------------
1405-08-97 : PCT ; Support texture mapping
15ajout pour deuxieme passe du texture mapping
16
17************************************************************************/
18
19#define G003 /* EUG 16-09-99 ZBufferAuto treatment
20*/
21
22/*----------------------------------------------------------------------*/
23/*
24* Includes
25*/
26
27#include <OpenGl_tgl_all.hxx>
28
29#include <stddef.h>
30#include <stdio.h>
31
32#include <OpenGl_cmn_varargs.hxx>
33#include <OpenGl_tsm.hxx>
34#include <OpenGl_tsm_ws.hxx>
35#include <OpenGl_Memory.hxx>
36
37static MtblPtr TsmMtblArray[TelLast];
38
39/* Fixed Header info for a structure */
40struct TSM_HEAD_STRUCT
41{
42 Tint num; /* number of elements present */
43};
44typedef TSM_HEAD_STRUCT TSM_HEAD;
45typedef TSM_HEAD_STRUCT* tsm_head;
46
47/* The head of the list when the structure is in the form of a list */
48struct TSM_LHEAD_STRUCT
49{
50 tsm_node next; // first list node
51 tsm_node prev; // last list node for reverse iteration
52 TSM_HEAD header;
53};
54typedef TSM_LHEAD_STRUCT TSM_LHEAD;
55typedef TSM_LHEAD_STRUCT *tsm_lhead;
56
57/* A Structure having fixed header and variable list of elements */
58struct TSM_STRUCT_STRUCT
59{
60 TSM_LHEAD elemListHead;
61 IMPLEMENT_MEMORY_OPERATORS
62};
63typedef TSM_STRUCT_STRUCT TSM_STRUCT;
64typedef TSM_STRUCT_STRUCT *tsm_struct;
65
66#define TsmStructureNotOpen -1
67#define TsmInvalidStructure -1
68
69/* Context maintained for the currently open structure */
70struct TSM_CONTEXT_STRUCT
71{
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 */
77};
78typedef TSM_CONTEXT_STRUCT TSM_CONTEXT;
79typedef TSM_CONTEXT_STRUCT* tsm_context;
80
81static TSM_CONTEXT context = { TsmInvalidStructure, TsmStructureNotOpen, 0, 0 };
82
83static TEditMode edit_mode;
84
85#define TSM_HTBL_SIZE 251
86typedef NCollection_List<TSM_NODE*> NodeList;
87typedef NCollection_DataMap<Tint, TSM_STRUCT*> StructMap;
88Handle(NCollection_BaseAllocator) _Allocator = NCollection_BaseAllocator::CommonBaseAllocator();
89static StructMap _StructMap( 1, _Allocator );
90
91
92
93/* Global workstation variable */
94Tint TglActiveWs; /* valid only during traversals */
95
96void
97TsmInitAllClasses( MtblPtr (**tbl)(TelType*), Tint size )
98{
99 register Tint i;
100 TelType el;
101 register MtblPtr fp;
102
103 for( i=0; i<size; i++ )
104 {
105 fp = tbl[i](&el);
106 TsmMtblArray[el] = fp;
107 }
108 return;
109}
110
111/* This function invokes the required method of the element type by looking
112up an array of Method Tables of each element.
113The arguments passed to the method are the data of the element and any
114other data that needs to be sent.
115In the case of ADD_TO_STRUCTURE methods, data should be the address of the
116element data. Other wise, it is the element data itself
117*/
118
119TStatus
120TsmSendMessage( TelType el, TMsgType msg, TSM_ELEM_DATA data, Tint n, ... )
121{
122#if defined (SOLARIS) || defined (IRIXO32)
123 cmn_key *k;
124#else
125 cmn_key k[TMaxArgs];
126
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.
130 k[0] = NULL;
131 // Uncomment the code below if you caught
132 // exception because of k[1] is NULL.
133 // Nullifies the whole array of "k"
134 //int i = TMaxArgs;
135 //while (--i)
136 // k[i] = NULL;
137
138#endif
139 TStatus TheStatus = TSuccess;
140
141 CMN_GET_STACK( n, k );
142
143 if( TsmMtblArray[el] && TsmMtblArray[el][msg] )
144 TheStatus = TsmMtblArray[el][msg]( data, n, k );
145 return TheStatus;
146}
147
148static void
149TsmFreeList( tsm_struct s )
150{
151 if ( !s )
152 return;
153
154 if( _Allocator.IsNull() )
155 return ;
156
157 tsm_node node, prev;
158 Tint num, i;
159
160 num = s->elemListHead.header.num;
161 node = s->elemListHead.next;
162
163 for( i=0; i<num; i++ )
164 {
165 TsmSendMessage( node->elem.el, Delete, node->elem.data, 0 );
166 prev = node;
167 node = node->next;
168 delete prev;
169 }
170
171 s->elemListHead.next = s->elemListHead.prev = (tsm_node)&(s->elemListHead);
172 s->elemListHead.header.num = 0;
173 return;
174}
175
176TStatus
177TsmOpenStructure( Tint stid )
178{
179 tsm_struct s = 0;
180
181 if( _Allocator.IsNull() )
182 return TFailure;
183
184 if( context.ind != TsmStructureNotOpen )
185 return TFailure; /* Some structure already open */
186
187 if ( !_StructMap.IsBound(stid) ){
188 s = new TSM_STRUCT();
189 if ( !s )
190 return TFailure; // Memory allocation failed
191
192 _StructMap.Bind( stid, s );
193 s->elemListHead.next = s->elemListHead.prev = (tsm_node)&(s->elemListHead);
194 s->elemListHead.header.num = 0;
195 }
196
197 s = _StructMap.Find(stid);
198
199 context.s = s;
200 context.stid = 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;
205
206 /* Ajout CAL, 14/09/95 */
207 /* on force l'update_state de toutes les wks a TNotDone */
208 TsmInitUpdateState ();
209
210 return TSuccess;
211}
212
213TStatus
214TsmCloseStructure()
215{
216 if( context.ind == TsmStructureNotOpen )
217 return TFailure; /* No structure currently open */
218
219 context.ind = TsmStructureNotOpen;
220
221 return TSuccess;
222}
223
224
225TStatus
226TsmDisplayStructure( Tint stid, Tint wsid )
227{
228 TSM_ELEM_DATA data;
229 CMN_KEY key;
230
231 TglActiveWs = wsid;
232
233 if( context.ind != TsmStructureNotOpen )
234 return TFailure; /* Some structure currently open */
235
236 key.id = wsid;
237 data.ldata = stid;
238 TsmSendMessage( TelExecuteStructure, DisplayTraverse, data, 1, &key );
239
240 return TSuccess;
241}
242
243TStatus
244TsmPrintStructure( Tint stid )
245{
246 tsm_node node;
247 Tint i, num;
248 tsm_struct s;
249
250 if( context.ind != TsmStructureNotOpen )
251 return TFailure; /* Some structure currently open */
252
253 if ( _StructMap.IsEmpty() )
254 return TFailure; /* No structure created yet */
255
256 /* Obtain structure pointer from hash table */
257 if ( !_StructMap.IsBound(stid) )
258 return TFailure; /* Non-existent structure */
259
260 s = _StructMap.Find(stid);
261
262 printf( "\nPRINT:" );
263 printf( "\n\tSTRUCTURE ID = %d", stid );
264 if( !s ){
265 num = 0;
266 node = 0;
267 }
268 else{
269 num = s->elemListHead.header.num;
270 node = s->elemListHead.next;
271 }
272
273 printf( "\n\tNUMBER OF ELEMENTS = %d", num);
274 printf( "\n" );
275
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 );
280 node = node->next;
281 }
282
283 return TSuccess;
284}
285
286TStatus
287TsmAddToStructure( TelType el, Tint n, ... )
288{
289 TSM_ELEM_DATA data;
290#if defined (SOLARIS) || defined (IRIXO32)
291 cmn_key *k;
292#else
293 cmn_key k[TMaxArgs];
294#endif
295
296 if( context.ind == TsmStructureNotOpen )
297 return TFailure; /* No structure currently open */
298
299 CMN_GET_STACK( n, k );
300 data.pdata = &data;
301 if( TsmSendMessage( el, Add, data, -n, k ) == TFailure )
302 return TFailure;
303
304 if( edit_mode == TEditReplace ){
305 TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 );
306 }
307 else{
308 tsm_node node = new TSM_NODE();
309
310 if( !node )
311 return TFailure;
312
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;
318
319 /* Make this node as current node */
320 context.n = node;
321 context.ind++;
322
323 /* Increment the no of elements */
324 context.s->elemListHead.header.num++;
325 }
326
327 context.n->elem.el = el;
328 context.n->elem.data = data;
329
330 return TSuccess;
331}
332
333TStatus
334TsmDeleteStructure( Tint stid )
335{
336 if( context.ind != TsmStructureNotOpen && context.stid == stid )
337 return TFailure; /* Same structure currently open */
338
339 if ( _StructMap.IsEmpty() )
340 return TFailure; /* No structure created yet */
341
342 if ( !_StructMap.IsBound(stid) )
343 return TFailure; /* Non-existent structure */
344
345 tsm_struct s = _StructMap.ChangeFind(stid);
346
347 if( stid == context.stid ){
348 context.stid = TsmInvalidStructure;
349 // Ensure the context doesn't point to freed memory
350 context.s = 0;
351 context.n = 0;
352 }
353
354 if( s ){
355 TsmFreeList( s );
356
357 /* Free structure memory */
358 delete s;
359 }
360
361 /* Remove hash table entry */
362 _StructMap.UnBind( stid );
363
364 /* Ajout BGN, 27/05/97 */
365 /* on force l'update_state de toutes les wks a TNotDone */
366 TsmInitUpdateState ();
367
368 return TSuccess;
369}
370
371TEditMode
372TsmSetEditMode( TEditMode mode )
373{
374 TEditMode m;
375
376 m = edit_mode;
377
378 /* Set static variable for mode */
379 edit_mode = mode;
380
381 /* return previous mode */
382 return m;
383}
384
385TStatus
386TsmDeleteElement()
387{
388 tsm_node node;
389
390 if( context.ind == TsmStructureNotOpen )
391 return TFailure; /* No structure currently open */
392
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()
396 if( !context.ind )
397 return TFailure;
398
399 /* Send message DELETE element */
400 TsmSendMessage( context.n->elem.el, Delete, context.n->elem.data, 0 );
401
402 node = context.n;
403 node->prev->next = node->next;
404 node->next->prev = node->prev;
405
406 /* make previous node as current node */
407 context.n = node->prev;
408 context.ind--;
409
410 /* Decrement the no of elements */
411 context.s->elemListHead.header.num--;
412
413 /* free the linked list node */
414 delete node;
415
416 return TSuccess;
417}
418
419TStatus
420TsmDeleteElementsBetweenLabels( Tint label_id1, Tint label_id2 )
421/* label_id1 & label_id2 exclusive */
422{
423 Tint elem1, elem2;
424
425 if( context.ind == TsmStructureNotOpen )
426 return TFailure; /* No structure currently open */
427
428 TsmSetElementPointer( 0 );
429
430 if( TsmSetElementPointerAtLabel( label_id1 ) == TFailure)
431 return TFailure;
432 elem1 = context.ind;
433
434 if( TsmSetElementPointerAtLabel( label_id2 ) == TFailure)
435 return TFailure;
436 elem2 = context.ind;
437
438 TsmDeleteElementRange( elem1, elem2 );
439
440 return TSuccess;
441}
442
443TStatus
444TsmDeleteElementRange( Tint elem1, Tint elem2 ) /* elem1 & elem2 exclusive */
445{
446 if( context.ind == TsmStructureNotOpen )
447 return TFailure; /* No structure currently open */
448
449 TsmSetElementPointer( elem2 - 1 );
450 while( context.ind != elem1 && context.ind )
451 TsmDeleteElement();
452
453 return TSuccess;
454}
455
456TStatus
457TsmSetElementPointer( Tint index )
458{
459 if( context.ind == TsmStructureNotOpen )
460 return TFailure; /* No structure currently open */
461
462 /* Set static variable accordingly */
463 if( context.ind == index ){
464 return TSuccess;
465 }
466 if( index >= context.s->elemListHead.header.num ){
467 index = context.s->elemListHead.header.num;
468 context.n = context.s->elemListHead.prev;
469 }
470 else if( index <= 0 ){
471 index = 0;
472 context.n = (tsm_node)&(context.s->elemListHead);
473 }
474 else{
475 Tint a, b, c, d;
476 tsm_node node;
477
478 a = index - 0;
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 ) ;
482
483 if( a == d ){
484 /* Traverse from head in forward direction */
485 d = index-1;
486 node = context.s->elemListHead.next;
487 while( d-- ){
488 node = node->next;
489 }
490 }
491 else if( b == d ){
492 /* Traverse from current node in appropriate direction */
493 node = context.n;
494 d = context.ind;
495 if( context.ind < index ){
496 while( d != index ){
497 node = node->next;
498 d++;
499 }
500 }
501 else{
502 while( d != index ){
503 node = node->prev;
504 d--;
505 }
506 }
507 }
508 else{ /* ( c == d ) */
509 /* Traverse from head in backward direction */
510 d = context.s->elemListHead.header.num;
511 node = context.s->elemListHead.prev;
512 while( d != index ){
513 node = node->prev;
514 d--;
515 }
516 }
517
518 context.n = node;
519 }
520
521 context.ind = index;
522
523 return TSuccess;
524}
525
526
527TStatus
528TsmSetElementPointerAtLabel( Tint label_id )
529{
530 Tint i, num;
531 tsm_node node;
532
533 if( context.ind == TsmStructureNotOpen )
534 return TFailure; /* No structure currently open */
535
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 ){
539 context.ind = i;
540 context.n = node;
541 return TSuccess;
542 }
543 }
544
545 return TFailure;
546}
547
548TStatus
549TsmOffsetElementPointer( Tint offset )
550{
551 return TsmSetElementPointer( context.ind + offset );
552}
553
554TStatus
555TsmGetStructure( Tint stid, Tint *num, tsm_node *n )
556{
557 if ( _StructMap.IsEmpty() )
558 return TFailure; /* No structure created yet */
559
560 if ( !_StructMap.IsBound(stid) )
561 return TFailure; /* Non-existent structure */
562
563 tsm_struct s = _StructMap.Find(stid);
564
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;
570
571 return TSuccess;
572}
573
574static TStatus
575GetDepth( Tint stid, Tint *depth )
576{
577 tsm_struct s;
578 Tint i, d, b, num;
579
580 if ( _StructMap.IsEmpty() )
581 return TFailure; /* No structure created yet */
582
583 if ( !_StructMap.IsBound(stid) )
584 return TFailure; /* Non-existent structure */
585
586 s = _StructMap.Find(stid);
587
588 (*depth)++;
589 d = b = *depth;
590
591 if( s ){
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 );
597 if( *depth < d )
598 *depth = d;
599 }
600 d = b;
601 node = node->next;
602 }
603 }
604
605 return TSuccess;
606}
607
608
609TStatus
610TsmGetStructureDepth( Tint stid, Tint *depth )
611{
612 *depth = 0;
613
614 GetDepth( stid, depth );
615 return TSuccess;
616}
617
618TStatus
619TsmGetCurElem( TSM_ELEM *elem )
620{
621 // Zero ind means no current element
622 if( context.ind == TsmStructureNotOpen ||
623 !context.ind )
624 return TFailure;
625
626 *elem = context.n->elem;
627 return TSuccess;
628}
629
630TStatus
631TsmGetCurElemPtr( Tint *ptr )
632{
633 // Zero ind means no current element
634 if( context.ind == TsmStructureNotOpen ||
635 !context.ind )
636 return TFailure;
637
638 *ptr = context.ind;
639 return TSuccess;
640}