OCC22354 Bug in Overlay Text rendering
[occt.git] / src / OpenGl / OpenGl_filters.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_filters :
6
7
8 REMARQUES:
9 ---------- 
10
11
12 HISTORIQUE DES MODIFICATIONS   :
13 --------------------------------
14 xx-xx-xx : xxx ; Creation.
15 11-03-96 : FMN ; Correction warning compilation
16 01-04-96 : CAL ; Integration MINSK portage WNT
17
18 ************************************************************************/
19
20 /*----------------------------------------------------------------------*/
21 /*
22 * Includes
23 */ 
24
25 #include <OpenGl_tgl_all.hxx>
26
27 #include <stdlib.h>
28 #include <stddef.h>
29
30 #include <OpenGl_telem.hxx>
31 #include <OpenGl_telem_util.hxx>
32 #include <OpenGl_telem_filters.hxx>
33 #include <OpenGl_tsm_ws.hxx>
34 #include <OpenGl_Memory.hxx>
35
36 /*----------------------------------------------------------------------*/
37 /*
38 * Definition des types
39 */
40
41 struct TGL_FILTERS
42 {
43   Tint     invis_incl_num,
44     invis_excl_num,
45     pick_incl_num,
46     pick_excl_num,
47     highl_incl_num,
48     highl_excl_num;
49
50   Tint     invis_incl_siz,
51     invis_excl_siz,
52     pick_incl_siz,
53     pick_excl_siz,
54     highl_incl_siz,
55     highl_excl_siz;
56
57   Tint    *invis_incl_lis,
58     *invis_excl_lis,
59     *pick_incl_lis,
60     *pick_excl_lis,
61     *highl_incl_lis,
62     *highl_excl_lis;
63
64   IMPLEMENT_MEMORY_OPERATORS
65 };
66 typedef TGL_FILTERS* tgl_filters;
67
68 struct TGL_NAMESET_NODE_STRUCT
69 {
70   Tint    num, siz, *ptr;
71   IMPLEMENT_MEMORY_OPERATORS
72 };
73 typedef TGL_NAMESET_NODE_STRUCT  TGL_NAMESET_NODE;
74 typedef TGL_NAMESET_NODE_STRUCT* tgl_nameset_node;
75
76
77 /*----------------------------------------------------------------------*/
78 /*
79 * Variables locales
80 */
81
82 typedef NCollection_Stack<TGL_NAMESET_NODE*> NodeStack;
83 typedef NCollection_List<TGL_FILTERS*> FilterList;
84
85 static NodeStack _NodeStack;
86 static FilterList _FilterList;
87
88
89 /*----------------------------------------------------------------------*/
90 /*
91 * Constantes
92 */
93
94 #define  LIST_GROW_SIZE  25
95 #define  FIL_STBL_SIZE   23
96
97 /*----------------------------------------------------------------------*/
98
99 static int
100 num_comp( const void* a, const void* b )
101 {
102   return *( Tint* )a - *( Tint* )b;
103 }
104
105 /*----------------------------------------------------------------------*/
106
107 static TStatus
108 set_filter( Tint n, Tint *ls, Tint *num, Tint *siz, Tint **list )
109 {
110   Tint  size;
111
112   size =  n,
113     size %= LIST_GROW_SIZE,
114     size += 1,
115     size *= LIST_GROW_SIZE;
116   if( !*siz )
117   {
118     //cmn_memreserve( *list, size, 0 );
119     *list = new Tint[size];
120     if( !*list )
121       return TFailure;
122
123     *siz = size;
124   }
125   else if( *siz < n )
126   {
127 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
128     *list = (Tint*)realloc( *list, size*sizeof(Tint) );
129 #else
130     *list = cmn_resizemem<Tint>( *list, size );
131 #endif
132     if( !*list )
133       return TFailure;
134
135     *siz = size;
136   }  
137   //cmn_memcpy<Tint>( *list, ls, n );
138   memcpy( *list, ls, n*sizeof(Tint) );
139   qsort( *list, n, sizeof(Tint), num_comp );
140   *num = TelRemdupnames( *list, n );
141
142   return TSuccess;
143 }
144
145 /*----------------------------------------------------------------------*/
146
147 static  tgl_filters
148 getfiltrec( Tint  wsid )
149 {
150   tgl_filters  filt;
151   CMN_KEY_DATA data;
152
153   if( TsmGetWSAttri( wsid, WSFilters, &data ) == TFailure )
154     return 0;
155
156   filt = (tgl_filters)data.pdata;
157   if( !filt )
158   {
159     filt = new TGL_FILTERS();
160     data.pdata = filt;
161     TsmSetWSAttri( wsid, WSFilters, &data );
162   }
163
164   return filt;
165 }
166
167 /*----------------------------------------------------------------------*/
168
169 TStatus
170 TglSetHighlFilter( Tint wsid, Tint in_num, Tint *in_lis,
171                   Tint ex_num, Tint *ex_lis )
172 {
173   TStatus  ret;
174   tgl_filters  filter;
175
176   filter = getfiltrec( wsid );
177   if( !filter )
178     return TFailure;
179
180   ret = set_filter( in_num, in_lis, &filter->highl_incl_num,
181     &filter->highl_incl_siz, &filter->highl_incl_lis );
182   if( ret == TSuccess )
183     ret = set_filter( ex_num, ex_lis, &filter->highl_excl_num,
184     &filter->highl_excl_siz, &filter->highl_excl_lis );
185   return ret;
186 }
187
188 /*----------------------------------------------------------------------*/
189
190 TStatus
191 TglSetPickFilter( Tint wsid, Tint in_num, Tint *in_lis,
192                  Tint ex_num, Tint *ex_lis )
193 {
194   TStatus  ret;
195   tgl_filters  filter;
196
197   filter = getfiltrec( wsid );
198   if( !filter )
199     return TFailure;
200
201   ret = set_filter( in_num, in_lis, &filter->pick_incl_num,
202     &filter->pick_incl_siz, &filter->pick_incl_lis );
203   if( ret == TSuccess )
204     ret = set_filter( ex_num, ex_lis, &filter->pick_excl_num,
205     &filter->pick_excl_siz, &filter->pick_excl_lis );
206   return ret;
207 }
208
209 /*----------------------------------------------------------------------*/
210
211 TStatus
212 TglSetInvisFilter( Tint wsid, Tint in_num, Tint *in_lis,
213                   Tint ex_num, Tint *ex_lis )
214 {
215   TStatus  ret;
216   tgl_filters  filter;
217
218   filter = getfiltrec( wsid );
219   if( !filter )
220     return TFailure;
221
222   ret = set_filter( in_num, in_lis, &filter->invis_incl_num,
223     &filter->invis_incl_siz, &filter->invis_incl_lis );
224   if( ret == TSuccess )
225     ret = set_filter( ex_num, ex_lis, &filter->invis_excl_num,
226     &filter->invis_excl_siz, &filter->invis_excl_lis );
227   return ret;
228 }
229
230 /*----------------------------------------------------------------------*/
231
232 TStatus
233 TglNamesetPush( void )
234 {
235   tgl_nameset_node  node;
236
237   node = new TGL_NAMESET_NODE();
238   if ( _NodeStack.IsEmpty() || !_NodeStack.Top() || !_NodeStack.Top()->ptr )
239     /* abd
240     if( !name_tail || !name_tail->ptr )*/
241   {
242     node->ptr = 0, node->num = node->siz = 0;
243   }
244   else /* copy previous stack entry to new one */
245   {
246     Tint  size = _NodeStack.Top()->siz;
247
248     node->ptr = new Tint[size];
249     if( !node->ptr )
250       return TFailure;
251
252     node->siz = size;
253     node->num = _NodeStack.Top()->num;
254     memcpy( node->ptr, _NodeStack.Top()->ptr, node->num*sizeof(Tint) );
255   }
256
257   _NodeStack.Push( node );
258
259   return TSuccess;
260 }
261
262 /*----------------------------------------------------------------------*/
263
264
265 TStatus
266 TglNamesetPop( void )
267 {
268   tgl_nameset_node node =
269     _NodeStack.ChangeTop();
270
271   _NodeStack.Pop();
272   if( node->ptr )
273   {
274     /* Remove entries from sorted list*/
275     delete[] node->ptr;
276   }
277   delete node;
278
279   return TSuccess;
280 }
281
282 /*----------------------------------------------------------------------*/
283
284 TStatus
285 TglNamesetAdd( Tint  num, Tint *set )
286 {
287   if (_NodeStack.IsEmpty())
288     return TFailure;
289
290   Tint  size;
291   tgl_nameset_node name_tail = _NodeStack.ChangeTop();
292
293   size = num,
294     size %= LIST_GROW_SIZE,
295     size++,
296     size *= LIST_GROW_SIZE;
297
298   if( !name_tail->ptr )
299   {
300     name_tail->ptr = new Tint[size];
301     if( !name_tail->ptr )
302       return TFailure;
303
304     name_tail->siz = size;
305   }
306   else if( name_tail->siz < name_tail->num + num )
307   {
308 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
309     name_tail->ptr = (Tint*)realloc( name_tail->ptr, size*sizeof(Tint) );
310 #else
311     name_tail->ptr = cmn_resizemem<Tint>( name_tail->ptr, size );
312 #endif
313     if( !name_tail->ptr )
314       return TFailure;
315
316     name_tail->siz = size;
317   }
318   memcpy( &name_tail->ptr[name_tail->num], set, num*sizeof(Tint) );
319   name_tail->num += num;
320
321   /* sort new set */
322   qsort( name_tail->ptr, name_tail->num, sizeof(Tint), num_comp );
323   name_tail->num = TelRemdupnames( name_tail->ptr, name_tail->num );
324
325   return TSuccess;
326 }
327
328 /*----------------------------------------------------------------------*/
329
330 TStatus
331 TglNamesetRemove( Tint num, Tint *set )
332 {
333   Tint  size, *ptr, *temp;
334   register  Tint  i, j, k, *prev;
335
336   if (_NodeStack.IsEmpty())
337     return TFailure;
338
339   tgl_nameset_node name_tail = _NodeStack.ChangeTop();
340
341   if( !name_tail || !name_tail->ptr || !num )
342     return TFailure;
343
344   ptr = new Tint[name_tail->siz];
345   if( !ptr )
346     return TFailure;
347
348   size = num, size %= LIST_GROW_SIZE, size++, size *= LIST_GROW_SIZE;
349   temp = new Tint[size];
350   if( !temp )
351     return TFailure;
352   memcpy( temp, set, num*sizeof(Tint) );
353
354   /* sort new set */
355   qsort( temp, num, sizeof(Tint), num_comp );
356   num = TelRemdupnames( temp, num );
357
358   prev = name_tail->ptr;
359   i = j = k = 0;
360   while(1)
361   {
362     if( prev[i] < temp[j] )
363       ptr[k++] = prev[i++];
364     else if( prev[i] > temp[j] )
365       j++;
366     else /* prev[i] == temp[j] */
367       i++, j++;
368     if( i == name_tail->num )
369       break;
370     if( j == num )
371     {
372       while( i < name_tail->num )
373         ptr[k++] = prev[i++];
374       break;
375     }
376   }
377   //cmn_freemem( temp );
378   delete[] temp;
379   //cmn_freemem( name_tail->ptr );
380   delete[] name_tail->ptr;
381
382   name_tail->ptr = ptr;
383   name_tail->num = k;
384
385   return TSuccess;
386 }
387
388 /*----------------------------------------------------------------------*/
389
390 static Tint
391 find( Tint num1, Tint *array1, Tint num2, Tint *array2 )
392 {
393   Tint i=0, j=0;
394
395   while(num1 && num2)
396   {
397     if( array1[i] < array2[j] )
398       i++;
399     else if( array1[i] > array2[j] )
400       j++;
401     else
402       return 1;
403
404     if( i == num1 || j == num2 )
405       return 0;
406   }
407   return 0;
408 }
409
410 /*----------------------------------------------------------------------*/
411
412 TStatus
413 TglFilterNameset( Tint  wsid, TFilterSet set )
414 {
415   tgl_filters  filter;
416   if (_NodeStack.IsEmpty())
417     return TFailure;
418
419   tgl_nameset_node name_tail = _NodeStack.ChangeTop();
420
421   filter = getfiltrec( wsid );
422   if( !filter )
423     return TFailure;
424
425   switch( set )
426   {
427   case InvisFilter:
428     {
429       if( find( filter->invis_excl_num, filter->invis_excl_lis,
430         name_tail->num, name_tail->ptr ) )
431         return TFailure;
432
433       if( find( filter->invis_incl_num, filter->invis_incl_lis,
434         name_tail->num, name_tail->ptr ) )
435         return TSuccess;
436
437       break;
438     }
439
440   case HighlFilter:
441     {
442       if( find( filter->highl_excl_num, filter->highl_excl_lis,
443         name_tail->num, name_tail->ptr ) )
444         return TFailure;
445
446       if( find( filter->highl_incl_num, filter->highl_incl_lis,
447         name_tail->num, name_tail->ptr ) )
448         return TSuccess;
449
450       break;
451     }
452
453   case PickFilter:
454     {
455       if( find( filter->pick_excl_num, filter->pick_excl_lis,
456         name_tail->num, name_tail->ptr ) )
457         return TFailure;
458
459       if( find( filter->pick_incl_num, filter->pick_incl_lis,
460         name_tail->num, name_tail->ptr ) )
461         return TSuccess;
462
463       break;
464     }
465   }
466
467   return TFailure;
468 }
469
470 /*----------------------------------------------------------------------*/
471
472 TStatus
473 TglDeleteFiltersForWS( Tint wsid )
474 {
475   CMN_KEY_DATA key;
476   tgl_filters  f;
477
478   TsmGetWSAttri( wsid, WSFilters, &key );
479   f = (tgl_filters)key.pdata;
480
481   if( !f )
482     return TSuccess;
483
484   if( f->invis_incl_siz )
485     //cmn_freemem( f->invis_incl_lis );
486     delete[] f->invis_incl_lis;
487   if( f->pick_incl_siz )
488     //cmn_freemem( f->pick_incl_lis );
489     delete[] f->pick_incl_lis;
490   if( f->highl_incl_siz )
491     //cmn_freemem( f->highl_incl_lis );
492     delete[] f->highl_incl_lis;
493   if( f->invis_excl_siz )
494     //cmn_freemem( f->invis_excl_lis );
495     delete[] f->invis_excl_lis;
496   if( f->pick_excl_siz )
497     //cmn_freemem( f->pick_excl_lis );
498     delete[] f->pick_excl_lis;
499   if( f->highl_excl_siz )
500     //cmn_freemem( f->highl_excl_lis );
501     delete[] f->highl_excl_lis;
502
503   //cmn_stg_tbl_free( f );
504   delete f;
505   return TSuccess;
506 }
507
508 /*----------------------------------------------------------------------*/