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