0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one...
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
1 // File:      OpenGl_Structure.cxx
2 // Created:   1 August 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #include <OpenGl_GlCore11.hxx>
7
8 #include <OpenGl_Structure.hxx>
9
10 #include <OpenGl_Polyline.hxx>
11 #include <OpenGl_Workspace.hxx>
12 #include <OpenGl_View.hxx>
13
14 #include <OpenGl_telem_util.hxx>
15
16
17 /*----------------------------------------------------------------------*/
18
19 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
20 {
21   int i, j;
22
23   for (i=0; i<4; i++)
24     for (j=0; j<4; j++)
25       tmat[j*4+i] = mat[i][j];
26 }
27
28 /*----------------------------------------------------------------------*/
29
30 OpenGl_Structure::OpenGl_Structure ()
31 : myTransformation(NULL),
32   myTransPers(NULL),
33   myDegenerateModel(NULL),
34   myAspectLine(NULL),
35   myAspectFace(NULL),
36   myAspectMarker(NULL),
37   myAspectText(NULL),
38   myHighlightBox(NULL),
39   myHighlightColor(NULL),
40   myNamedStatus(0),
41   myZLayer(0)
42 {
43 }
44
45 /*----------------------------------------------------------------------*/
46
47 OpenGl_Structure::~OpenGl_Structure ()
48 {
49   if (myTransformation)
50   {
51     delete myTransformation;
52     myTransformation = NULL;
53   }
54   if (myTransPers)
55   {
56     delete myTransPers;
57     myTransPers = NULL;
58   }
59   if (myDegenerateModel)
60   {
61     delete myDegenerateModel;
62     myDegenerateModel = NULL;
63   }
64   if (myAspectLine)
65   {
66     delete myAspectLine;
67     myAspectLine = NULL;
68   }
69   if (myAspectFace)
70   {
71     delete myAspectFace;
72     myAspectFace = NULL;
73   }
74   if (myAspectMarker)
75   {
76     delete myAspectMarker;
77     myAspectMarker = NULL;
78   }
79   if (myAspectText)
80   {
81     delete myAspectText;
82     myAspectText = NULL;
83   }
84   ClearHighlightColor();
85   // Delete groups
86   Clear();
87 }
88
89 /*----------------------------------------------------------------------*/
90
91 void OpenGl_Structure::SetTransformation(const float *AMatrix)
92 {
93   if (!myTransformation)
94     myTransformation = new OpenGl_Matrix;
95
96   matcpy( myTransformation->mat, AMatrix );
97 }
98
99 /*----------------------------------------------------------------------*/
100
101 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
102 {
103   if (!myTransPers)
104     myTransPers = new TEL_TRANSFORM_PERSISTENCE;
105
106   myTransPers->mode = ATransPers.Flag;
107   myTransPers->pointX = ATransPers.Point.x;
108   myTransPers->pointY = ATransPers.Point.y;
109   myTransPers->pointZ = ATransPers.Point.z;
110 }
111
112 /*----------------------------------------------------------------------*/
113
114 void OpenGl_Structure::SetDegenerateModel (const Standard_Integer AMode, const float ASkipRatio)
115 {
116   if (!myDegenerateModel)
117     myDegenerateModel = new DEGENERATION;
118
119   myDegenerateModel->mode = AMode;
120   myDegenerateModel->skipRatio = ASkipRatio;
121 }
122
123 /*----------------------------------------------------------------------*/
124
125 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
126 {
127   if (!myAspectLine)
128     myAspectLine = new OpenGl_AspectLine;
129   myAspectLine->SetContext( AContext );
130 }
131
132 /*----------------------------------------------------------------------*/
133
134 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
135 {
136   if (!myAspectFace)
137     myAspectFace = new OpenGl_AspectFace;
138   myAspectFace->SetContext( AContext );
139 }
140
141 /*----------------------------------------------------------------------*/
142
143 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
144 {
145   if (!myAspectMarker)
146     myAspectMarker = new OpenGl_AspectMarker;
147   myAspectMarker->SetContext( AContext );
148 }
149
150 /*----------------------------------------------------------------------*/
151
152 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
153 {
154   if (!myAspectText)
155     myAspectText = new OpenGl_AspectText;
156   myAspectText->SetContext( AContext );
157 }
158
159 /*----------------------------------------------------------------------*/
160
161 void OpenGl_Structure::SetHighlightBox (const CALL_DEF_BOUNDBOX &ABoundBox)
162 {
163   if (!myHighlightBox)
164     myHighlightBox = new OpenGl_Group;
165   else
166     myHighlightBox->Clear();
167
168   CALL_DEF_CONTEXTLINE context_line;
169   context_line.Color = ABoundBox.Color;
170   context_line.LineType = Aspect_TOL_SOLID;
171   context_line.Width = 1.0f;
172   myHighlightBox->SetAspectLine( context_line );
173
174 #define CALL_MAX_BOUNDBOXSIZE 16
175
176   Graphic3d_Array1OfVertex points(1,CALL_MAX_BOUNDBOXSIZE);
177   const float Xm = ABoundBox.Pmin.x;
178   const float Ym = ABoundBox.Pmin.y;
179   const float Zm = ABoundBox.Pmin.z;
180   const float XM = ABoundBox.Pmax.x;
181   const float YM = ABoundBox.Pmax.y;
182   const float ZM = ABoundBox.Pmax.z;
183   points( 1).SetCoord(Xm,Ym,Zm);
184   points( 2).SetCoord(Xm,Ym,ZM);
185   points( 3).SetCoord(Xm,YM,ZM);
186   points( 4).SetCoord(Xm,YM,Zm);
187   points( 5).SetCoord(Xm,Ym,Zm);
188   points( 6).SetCoord(XM,Ym,Zm);
189   points( 7).SetCoord(XM,Ym,ZM);
190   points( 8).SetCoord(XM,YM,ZM);
191   points( 9).SetCoord(XM,YM,Zm);
192   points(10).SetCoord(XM,Ym,Zm);
193   points(11).SetCoord(XM,YM,Zm);
194   points(12).SetCoord(Xm,YM,Zm);
195   points(13).SetCoord(Xm,YM,ZM);
196   points(14).SetCoord(XM,YM,ZM);
197   points(15).SetCoord(XM,Ym,ZM);
198   points(16).SetCoord(Xm,Ym,ZM);
199
200   OpenGl_Polyline *apolyline = new OpenGl_Polyline(points);
201   myHighlightBox->AddElement( TelPolyline, apolyline );
202 }
203
204 /*----------------------------------------------------------------------*/
205
206 void OpenGl_Structure::ClearHighlightBox ()
207 {
208   if (myHighlightBox)
209   {
210     delete myHighlightBox;
211     myHighlightBox = NULL;
212   }
213 }
214
215 /*----------------------------------------------------------------------*/
216
217 void OpenGl_Structure::SetHighlightColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
218 {
219   ClearHighlightBox();
220   if (!myHighlightColor)
221     myHighlightColor = new TEL_COLOUR;
222
223   myHighlightColor->rgb[0] = R;
224   myHighlightColor->rgb[1] = G;
225   myHighlightColor->rgb[2] = B;
226   myHighlightColor->rgb[3] = 1.F;
227 }
228
229 /*----------------------------------------------------------------------*/
230
231 void OpenGl_Structure::ClearHighlightColor ()
232 {
233   ClearHighlightBox();
234   if (myHighlightColor)
235   {
236     delete myHighlightColor;
237     myHighlightColor = NULL;
238   }
239 }
240
241 /*----------------------------------------------------------------------*/
242
243 void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
244 {
245   Disconnect (AStructure);
246   myConnected.Append(AStructure);
247 }
248
249 /*----------------------------------------------------------------------*/
250
251 void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
252 {
253   OpenGl_ListOfStructure::Iterator its(myConnected);
254   while (its.More())
255   {
256     // Check for the given structure
257     if (its.Value() == AStructure)
258     {
259       myConnected.Remove(its);
260       return;
261     }
262     its.Next();
263   }
264 }
265
266 /*----------------------------------------------------------------------*/
267
268 OpenGl_Group * OpenGl_Structure::AddGroup ()
269 {
270   // Create new group
271   OpenGl_Group *g = new OpenGl_Group;
272   myGroups.Append(g);
273   return g;
274 }
275
276 /*----------------------------------------------------------------------*/
277
278 void OpenGl_Structure::RemoveGroup (const OpenGl_Group *AGroup)
279 {
280   OpenGl_ListOfGroup::Iterator itg(myGroups);
281   while (itg.More())
282   {
283     // Check for the given group
284     if (itg.Value() == AGroup)
285     {
286       // Delete object
287       delete AGroup;
288       myGroups.Remove(itg);
289       return;
290     }
291     itg.Next();
292   }
293 }
294
295 /*----------------------------------------------------------------------*/
296
297 void OpenGl_Structure::Clear ()
298 {
299   OpenGl_ListOfGroup::Iterator itg(myGroups);
300   while (itg.More())
301   {
302     // Delete objects
303     delete itg.Value();
304     itg.Next();
305   }
306   myGroups.Clear();
307 }
308
309 /*----------------------------------------------------------------------*/
310
311 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
312 {
313   // Process the structure only if visible
314   if ( myNamedStatus & OPENGL_NS_HIDE )
315     return;
316
317   // Render named status
318   const Standard_Integer named_status = AWorkspace->NamedStatus;
319   AWorkspace->NamedStatus |= myNamedStatus;
320
321   // Is rendering in ADD or IMMEDIATE mode?
322   const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
323
324   // Apply local transformation
325   GLint matrix_mode = 0;
326   const OpenGl_Matrix *local_trsf = NULL;
327   if (myTransformation)
328   {
329     if (isImmediate)
330     {
331       float mat16[16];
332       call_util_transpose_mat (mat16, myTransformation->mat);
333       glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
334       glMatrixMode (GL_MODELVIEW);
335       glPushMatrix ();
336       glScalef (1.F, 1.F, 1.F);
337       glMultMatrixf (mat16);
338     }
339     else
340     {
341       glMatrixMode (GL_MODELVIEW);
342       glPushMatrix();
343
344       local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
345     }
346   }
347
348   // Apply transform persistence
349   const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
350   if ( myTransPers && myTransPers->mode != 0 )
351   {
352     trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
353   }
354
355   // Apply degeneration
356   if (myDegenerateModel)
357   {
358     if ( AWorkspace->NamedStatus & OPENGL_NS_DEGENERATION )
359     {
360       AWorkspace->DegenerateModel = myDegenerateModel->mode;
361       switch ( AWorkspace->DegenerateModel )
362       {
363         case 0: break;
364
365         default:
366           glLineWidth ( 1.0 );
367           glDisable   ( GL_LINE_STIPPLE );
368
369         case 1:
370           AWorkspace->SkipRatio = myDegenerateModel->skipRatio;
371       }
372     }
373   }
374
375   // Apply aspects
376   const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
377   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
378   const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
379   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
380   if (myAspectLine)
381     AWorkspace->SetAspectLine(myAspectLine);
382   if (myAspectFace)
383     AWorkspace->SetAspectFace(myAspectFace);
384   if (myAspectMarker)
385     AWorkspace->SetAspectMarker(myAspectMarker);
386   if (myAspectText)
387     AWorkspace->SetAspectText(myAspectText);
388
389   // Apply highlight box
390   if (myHighlightBox)
391     myHighlightBox->Render( AWorkspace );
392
393   // Apply highlight color
394   const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
395   if (myHighlightColor)
396     AWorkspace->HighlightColor = myHighlightColor;
397
398   // Render connected structures
399   OpenGl_ListOfStructure::Iterator its(myConnected);
400   while (its.More())
401   {
402     its.Value()->Render(AWorkspace);
403     its.Next();
404   }
405
406   // Render groups
407   OpenGl_ListOfGroup::Iterator itg(myGroups);
408   while (itg.More())
409   {
410     itg.Value()->Render(AWorkspace);
411     itg.Next();
412   }
413
414   // Restore highlight color
415   AWorkspace->HighlightColor = highlight_color;
416
417   // Restore aspects
418   AWorkspace->SetAspectLine(aspect_line);
419   AWorkspace->SetAspectFace(aspect_face);
420   AWorkspace->SetAspectMarker(aspect_marker);
421   AWorkspace->SetAspectText(aspect_text);
422
423   // Restore transform persistence
424   if ( myTransPers && myTransPers->mode != 0 )
425   {
426     AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
427   }
428
429   // Restore local transformation
430   if (myTransformation)
431   {
432     if (isImmediate)
433     {
434       glPopMatrix ();
435       glMatrixMode (matrix_mode);
436     }
437     else
438     {
439       AWorkspace->SetStructureMatrix(local_trsf);
440
441       glMatrixMode (GL_MODELVIEW);
442       glPopMatrix();
443     }
444   }
445
446   // Restore named status
447   AWorkspace->NamedStatus = named_status;
448 }
449
450 //=======================================================================
451 //function : SetZLayer
452 //purpose  : 
453 //=======================================================================
454
455 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
456 {
457   myZLayer = theLayerIndex;
458 }
459
460 //=======================================================================
461 //function : GetZLayer
462 //purpose  : 
463 //=======================================================================
464
465 Standard_Integer OpenGl_Structure::GetZLayer () const
466 {
467   return myZLayer;
468 }