0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_polyl.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_polyl :
6
7
8 REMARQUES:
9 ---------- 
10
11
12 HISTORIQUE DES MODIFICATIONS   :
13 --------------------------------
14 xx-xx-xx : xxx ; Creation.
15 21-10-96 : FMN ; Suppression LMC_COLOR fait dans OpenGl_execstruct.c
16
17 ************************************************************************/
18
19 #define G003    /* EUG 07-10-99 Degeneration mode support
20 */
21
22 #define IMP190602       /* GG Avoid memory leaks after creating a polyline
23 //                      with vertex colors primitive.
24 //                      Thanks to Ivan Fontaine (SAMTECH) for this improvment
25 */
26
27 /*----------------------------------------------------------------------*/
28 /*
29 * Includes
30 */ 
31
32 #include <OpenGl_tgl_all.hxx>
33
34 #include <stddef.h>
35 #include <stdio.h>
36 #include <GL/gl.h>
37 #include <GL/glu.h>
38
39 #include <OpenGl_cmn_varargs.hxx>
40 #include <OpenGl_telem_attri.hxx>
41 #include <OpenGl_telem_highlight.hxx>
42 #include <OpenGl_tsm.hxx>
43 #include <OpenGl_telem.hxx>
44 #include <OpenGl_telem_inquire.hxx>
45 #include <OpenGl_Memory.hxx>
46
47 #ifdef G003
48 extern int g_nDegenerateModel;
49 #endif  /* G003 */
50
51 static  TStatus  PolylineDisplay( TSM_ELEM_DATA, Tint, cmn_key* );
52 static  TStatus  PolylineAdd( TSM_ELEM_DATA, Tint, cmn_key* );
53 static  TStatus  PolylineDelete( TSM_ELEM_DATA, Tint, cmn_key* );
54 static  TStatus  PolylinePrint( TSM_ELEM_DATA, Tint, cmn_key* );
55 static  TStatus  PolylineInquire( TSM_ELEM_DATA, Tint, cmn_key* );
56
57 /*static  GLboolean         lighting_mode;*/
58
59 static  TStatus  (*MtdTbl[])( TSM_ELEM_DATA, Tint, cmn_key* ) =
60 {
61   PolylineDisplay,
62   PolylineDisplay,
63   PolylineAdd,
64   PolylineDelete,
65   PolylinePrint,
66   PolylineInquire
67 };
68
69 struct TEL_LINE_DATA
70 {
71   Tint       num_lines;       /* Number of polylines */
72   Tint       num_vertices;    /* Number of vertices in vertices array */
73   Tint       *bounds;         /* Array of number of points in each polyline */
74   tel_colour vcolours;        /* vertex colour values for each vertex */
75   tel_point  vertices;        /* vertices array of length num_vertices */
76   IMPLEMENT_MEMORY_OPERATORS
77 };
78 typedef TEL_LINE_DATA* tel_line_data;
79
80 MtblPtr
81 TelPolylineInitClass( TelType* el )
82 {
83   *el = TelPolyline;
84   return MtdTbl;
85 }
86
87 static  TStatus
88 PolylineAdd( TSM_ELEM_DATA d, Tint n, cmn_key *k )
89
90 {
91   Tint          i, j;
92   tel_line_data p;
93
94   for( i = 0; i < n; i++ )
95   {
96     if( k[i]->id == NUM_LINES_ID )
97       break;
98   }
99
100   if( i == n )
101     return TFailure;
102
103   if( !(k[i]->data.ldata) )
104     return TFailure;
105
106   for( j = 0; j < n; j++ )
107   {
108     if( k[j]->id == BOUNDS_DATA_ID )
109       break;
110   }
111
112   if( j == n )
113     return TFailure;
114
115   p = new TEL_LINE_DATA();
116   p->num_lines = k[i]->data.ldata;
117   p->bounds = new Tint[p->num_lines];
118   memcpy( p->bounds, k[j]->data.pdata, p->num_lines*sizeof(Tint) );
119
120   p->num_vertices = 0;
121   for( i = 0; i < p->num_lines; i++ )
122   {
123     p->num_vertices += p->bounds[i];
124   }
125
126   for( i = 0; i < n; i++ )
127   {
128     switch( k[i]->id )
129     {
130     case VERTEX_COLOUR_VALS_ID:
131       p->vcolours = new TEL_COLOUR[p->num_vertices];
132       memcpy( p->vcolours, k[i]->data.pdata, p->num_vertices*sizeof(TEL_COLOUR) );
133       break;
134
135     case VERTICES_ID:
136       p->vertices = new TEL_POINT[p->num_vertices];
137       memcpy( p->vertices, k[i]->data.pdata, p->num_vertices*sizeof(TEL_POINT) );
138       break;
139     }
140   }
141
142   ((tsm_elem_data)(d.pdata))->pdata = p;
143
144   return TSuccess;
145 }
146
147
148 static  TStatus
149 PolylineDisplay( TSM_ELEM_DATA data, Tint n, cmn_key *k )
150 {
151   tel_line_data   d;
152   Tint            i, j, a;
153   CMN_KEY         key;
154   TEL_COLOUR      colour;
155
156   d = (tel_line_data)data.pdata;
157
158   /* OCC11904 -- Temporarily disable environment mapping */
159   glPushAttrib(GL_ENABLE_BIT);
160   glDisable(GL_TEXTURE_1D);
161   glDisable(GL_TEXTURE_2D);
162
163   if( k[0]->id == TOn )
164   {                           /* Use highlight colours */
165     TEL_HIGHLIGHT  hrep;
166
167     key.id = TelHighlightIndex;
168     TsmGetAttri( 1, &key );
169     if( TelGetHighlightRep( TglActiveWs, key.data.ldata, &hrep )
170       == TSuccess )
171       colour = hrep.col;
172     else
173     {
174       TelGetHighlightRep( TglActiveWs, 0, &hrep );
175       colour = hrep.col;
176     }
177   }
178   else
179   {
180     key.id = TelPolylineColour;
181     key.data.pdata = &colour;
182     TsmGetAttri( 1, &key );
183   }
184
185   if( !d->vcolours )
186   {
187     glColor3fv( colour.rgb );
188     for( i = 0, j = 0, a = 0; i < d->num_lines; i++ )
189     {
190       a = j + d->bounds[i];
191 #ifdef G003
192       glBegin ( g_nDegenerateModel != 3 ? GL_LINE_STRIP : GL_POINTS );
193 #else
194       glBegin(GL_LINE_STRIP);
195 #endif  /* G003 */
196       for( ; j < a; j++ )
197         glVertex3fv( d->vertices[j].xyz );
198       glEnd();
199     }
200   }
201   else
202   {
203     for( i = 0, j = 0, a = 0; i < d->num_lines; i++ )
204     {
205       a = j + d->bounds[i];
206 #ifdef G003
207       glBegin ( g_nDegenerateModel != 3 ? GL_LINE_STRIP : GL_POINTS );
208 #else
209       glBegin(GL_LINE_STRIP);
210 #endif  /* G003 */
211       for( ; j < a; j++ )
212       {
213         glColor3fv( d->vcolours[j].rgb );
214         glVertex3fv( d->vertices[j].xyz );
215       }
216       glEnd();
217     }
218
219   }
220
221   glPopAttrib();
222   return TSuccess;
223 }
224
225
226 static  TStatus
227 PolylineDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k )
228 {
229   tel_line_data p = (tel_line_data)data.pdata;
230   if( p->bounds )
231     delete[] p->bounds;
232   if( p->vertices )
233     delete[] p->vertices;
234 #ifdef IMP190602
235   if( p->vcolours )
236     delete[] p->vcolours;
237 #endif
238   if (data.pdata)
239     delete data.pdata;
240
241   return TSuccess;
242 }
243
244
245
246
247 static  TStatus
248 PolylinePrint( TSM_ELEM_DATA data, Tint n, cmn_key *k )
249 {
250   Tint           i;
251   tel_line_data  p = (tel_line_data)data.pdata;
252
253   fprintf( stdout, "TelPolyline. Number of Lines: %d\n", p->num_lines );
254
255   if( p->vcolours )
256     fprintf( stdout, "\t\tVertex Flag : COLOUR\n" );
257   else
258     fprintf( stdout, "\t\tVertex Flag : NONE\n" );
259
260   if( p->bounds )
261   {
262     fprintf( stdout, "\t\tLengths array :\n" );
263     for( i = 0; i < p->num_lines; i++ )
264       fprintf( stdout, "\t\tL[%d] %d \n", i, p->bounds[i] );
265   }
266
267   if( p->vertices )
268   {
269     fprintf( stdout, "\n\t\tVertices : " );
270     for( i = 0; i < p->num_vertices; i++ )
271       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
272       p->vertices[i].xyz[0],
273       p->vertices[i].xyz[1],
274       p->vertices[i].xyz[2] );    }
275
276   fprintf( stdout, "\n" );
277
278   if( p->vcolours )
279   {
280     fprintf( stdout, "\n\t\tVertex Colours : " );
281     for( i = 0; i < p->num_vertices; i++ )
282       fprintf( stdout, "\n\t\t v[%d] = %g %g %g", i,
283       p->vcolours[i].rgb[0],
284       p->vcolours[i].rgb[1],
285       p->vcolours[i].rgb[2] );    }
286   else
287     fprintf( stdout, "\n\t\tVertex Colours not specified\n" );
288
289   fprintf( stdout, "\n" );
290
291   return TSuccess;
292 }
293
294 static TStatus
295 PolylineInquire( TSM_ELEM_DATA data, Tint n, cmn_key *k )
296 {
297   Tint          i;
298   tel_line_data d;
299   Tint          size_reqd=0;
300   TStatus       status = TSuccess;
301
302   d = (tel_line_data)data.pdata;
303
304   size_reqd  = d->num_lines * sizeof( Tint );
305   size_reqd += ( d->num_vertices * sizeof( TEL_POINT ) );
306   if( d->vcolours )
307   {
308     size_reqd += ( d->num_vertices * sizeof( TEL_COLOUR ) );
309   }
310
311   for( i = 0; i < n; i++ )
312   {
313     switch( k[i]->id )
314     {
315     case INQ_GET_SIZE_ID:
316       {
317         k[i]->data.ldata = size_reqd;
318         break;
319       }
320
321     case INQ_GET_CONTENT_ID:
322       {
323         TEL_INQ_CONTENT *c;
324         Teldata         *w;
325
326         c = (tel_inq_content)k[i]->data.pdata;
327         c->act_size = size_reqd;
328         w = c->data;
329         w->lineset3data.num_bounds = d->num_lines;
330
331         if( d->vcolours )
332           w->lineset3data.vrtflag = TEL_VTFLAG_COLOUR;
333         else
334           w->lineset3data.vrtflag = TEL_VTFLAG_NONE;
335
336         if( c->size >= size_reqd )
337         {
338           w->lineset3data.bounds = (Tint *)(c->buf);
339           memcpy( w->lineset3data.bounds, d->bounds, d->num_lines*sizeof(Tint) );
340
341           w->lineset3data.points =
342             (tel_point)(c->buf + d->num_lines * sizeof( Tint ) );
343
344           memcpy( w->lineset3data.points, d->vertices, d->num_vertices*sizeof(TEL_POINT) );
345           if( d->vcolours )
346           {
347             w->lineset3data.colours = (tel_colour)( c->buf +
348               d->num_lines * sizeof( Tint ) +
349               d->num_vertices * sizeof( TEL_POINT ));
350             memcpy( w->lineset3data.colours, d->vcolours, d->num_vertices*sizeof(TEL_COLOUR) );
351           }
352           else
353             w->lineset3data.colours = 0;
354
355           status = TSuccess;
356         }
357         else
358           status = TFailure;
359         break;
360       }
361     }
362   }
363   return status;
364 }