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