0024276: Memory leak due to a static variable
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
CommitLineData
b311480e 1// Created on: 2011-08-01
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
5f8b738e 20#include <OpenGl_GlCore11.hxx>
21
2166f0fa
SK
22#include <OpenGl_Structure.hxx>
23
2166f0fa 24#include <OpenGl_Workspace.hxx>
27eed937 25#include <OpenGl_Vec.hxx>
2166f0fa 26#include <OpenGl_View.hxx>
4269bd1b 27#include <OpenGl_CappingAlgo.hxx>
28#include <OpenGl_Context.hxx>
2166f0fa
SK
29#include <OpenGl_telem_util.hxx>
30
b859a34d 31#include <Graphic3d_SetOfHClipPlane_Handle.hxx>
32
27eed937 33//! Auxiliary class for bounding box presentation
34class OpenGl_BndBoxPrs : public OpenGl_Element
35{
36
37public:
38
39 //! Main constructor
40 OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
41 {
42 const float Xm = theBndBox.Pmin.x;
43 const float Ym = theBndBox.Pmin.y;
44 const float Zm = theBndBox.Pmin.z;
45 const float XM = theBndBox.Pmax.x;
46 const float YM = theBndBox.Pmax.y;
47 const float ZM = theBndBox.Pmax.z;
48 myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
49 myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
50 myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
51 myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm);
52 myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm);
53 myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm);
54 myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM);
55 myVerts[7] = OpenGl_Vec3 (XM, YM, ZM);
56 myVerts[8] = OpenGl_Vec3 (XM, YM, Zm);
57 myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm);
58 myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
59 myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
60 myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
61 myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
62 myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
63 myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
64 }
65
66 //! Render presentation
67 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
68 {
69 // Apply line aspect
70 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
71 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
72
73 glDisable (GL_LIGHTING);
74 if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
75 {
76 glDepthMask (GL_FALSE);
77 }
78
79 // Use highlight colors
80 glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
81
82 glEnableClientState (GL_VERTEX_ARRAY);
83 glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
84 glDrawArrays (GL_LINE_STRIP, 0, 16);
85 glDisableClientState (GL_VERTEX_ARRAY);
86
87 // restore aspects
88 if (!aPrevTexture.IsNull())
89 {
90 theWorkspace->EnableTexture (aPrevTexture);
91 }
92 }
93
94 //! Release graphical resources
95 virtual void Release (const Handle(OpenGl_Context)& )
96 {
97 //
98 }
99
100protected:
101
102 //! Protected destructor
103 virtual ~OpenGl_BndBoxPrs() {}
104
105private:
106
107 OpenGl_Vec3 myVerts[16]; //!< vertices array
108
109public:
110
111 DEFINE_STANDARD_ALLOC
112
113};
2166f0fa
SK
114
115/*----------------------------------------------------------------------*/
116
4269bd1b 117// =======================================================================
118// function : call_util_transpose_mat
119// purpose :
120// =======================================================================
2166f0fa
SK
121static void call_util_transpose_mat (float tmat[16], float mat[4][4])
122{
123 int i, j;
124
125 for (i=0; i<4; i++)
126 for (j=0; j<4; j++)
127 tmat[j*4+i] = mat[i][j];
128}
129
4269bd1b 130// =======================================================================
131// function : OpenGl_Structure
132// purpose :
133// =======================================================================
2166f0fa
SK
134OpenGl_Structure::OpenGl_Structure ()
135: myTransformation(NULL),
136 myTransPers(NULL),
2166f0fa
SK
137 myAspectLine(NULL),
138 myAspectFace(NULL),
139 myAspectMarker(NULL),
140 myAspectText(NULL),
141 myHighlightBox(NULL),
142 myHighlightColor(NULL),
59f45b7c 143 myNamedStatus(0),
144 myZLayer(0)
2166f0fa
SK
145{
146}
147
4269bd1b 148// =======================================================================
149// function : ~OpenGl_Structure
150// purpose :
151// =======================================================================
5e27df78 152OpenGl_Structure::~OpenGl_Structure()
2166f0fa 153{
5e27df78 154 Release (Handle(OpenGl_Context)());
155 delete myTransformation; myTransformation = NULL;
156 delete myTransPers; myTransPers = NULL;
2166f0fa
SK
157}
158
4269bd1b 159// =======================================================================
160// function : SetTransformation
161// purpose :
162// =======================================================================
2166f0fa
SK
163void OpenGl_Structure::SetTransformation(const float *AMatrix)
164{
165 if (!myTransformation)
5e27df78 166 myTransformation = new OpenGl_Matrix();
2166f0fa
SK
167
168 matcpy( myTransformation->mat, AMatrix );
169}
170
4269bd1b 171// =======================================================================
172// function : SetTransformPersistence
173// purpose :
174// =======================================================================
2166f0fa
SK
175void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
176{
177 if (!myTransPers)
178 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
179
180 myTransPers->mode = ATransPers.Flag;
181 myTransPers->pointX = ATransPers.Point.x;
182 myTransPers->pointY = ATransPers.Point.y;
183 myTransPers->pointZ = ATransPers.Point.z;
184}
185
4269bd1b 186// =======================================================================
187// function : SetAspectLine
188// purpose :
189// =======================================================================
fd4a6963 190void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
2166f0fa
SK
191{
192 if (!myAspectLine)
fd4a6963 193 {
5e27df78 194 myAspectLine = new OpenGl_AspectLine();
fd4a6963 195 }
196 myAspectLine->SetAspect (theAspect);
2166f0fa
SK
197}
198
4269bd1b 199// =======================================================================
200// function : SetAspectFace
201// purpose :
202// =======================================================================
fd4a6963 203void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
2166f0fa
SK
204{
205 if (!myAspectFace)
bf75be98 206 {
5e27df78 207 myAspectFace = new OpenGl_AspectFace();
bf75be98 208 }
fd4a6963 209 myAspectFace->SetAspect (theAspect);
2166f0fa
SK
210}
211
4269bd1b 212// =======================================================================
213// function : SetAspectMarker
214// purpose :
215// =======================================================================
fd4a6963 216void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
2166f0fa
SK
217{
218 if (!myAspectMarker)
a577aaab 219 {
5e27df78 220 myAspectMarker = new OpenGl_AspectMarker();
a577aaab 221 }
fd4a6963 222 myAspectMarker->SetAspect (theAspect);
2166f0fa
SK
223}
224
4269bd1b 225// =======================================================================
226// function : SetAspectText
227// purpose :
228// =======================================================================
fd4a6963 229void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
2166f0fa
SK
230{
231 if (!myAspectText)
fd4a6963 232 {
5e27df78 233 myAspectText = new OpenGl_AspectText();
fd4a6963 234 }
235 myAspectText->SetAspect (theAspect);
2166f0fa
SK
236}
237
4269bd1b 238// =======================================================================
239// function : SetHighlightBox
240// purpose :
241// =======================================================================
5e27df78 242void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
243 const CALL_DEF_BOUNDBOX& theBoundBox)
2166f0fa 244{
5e27df78 245 if (myHighlightBox != NULL)
246 {
247 myHighlightBox->Release (theGlCtx);
248 }
2166f0fa 249 else
5e27df78 250 {
251 myHighlightBox = new OpenGl_Group();
252 }
2166f0fa 253
5e27df78 254 CALL_DEF_CONTEXTLINE aContextLine;
255 aContextLine.Color = theBoundBox.Color;
256 aContextLine.LineType = Aspect_TOL_SOLID;
257 aContextLine.Width = 1.0f;
258 myHighlightBox->SetAspectLine (aContextLine);
2166f0fa 259
27eed937 260 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
261 myHighlightBox->AddElement (TelParray, aBndBoxPrs);
2166f0fa
SK
262}
263
4269bd1b 264// =======================================================================
265// function : ClearHighlightBox
266// purpose :
267// =======================================================================
5e27df78 268void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 269{
5e27df78 270 if (myHighlightBox != NULL)
2166f0fa 271 {
5e27df78 272 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
2166f0fa
SK
273 }
274}
275
4269bd1b 276// =======================================================================
277// function : SetHighlightColor
278// purpose :
279// =======================================================================
5e27df78 280void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
281 const Standard_ShortReal R,
282 const Standard_ShortReal G,
283 const Standard_ShortReal B)
2166f0fa 284{
5e27df78 285 ClearHighlightBox (theGlCtx);
286 if (myHighlightColor == NULL)
287 {
288 myHighlightColor = new TEL_COLOUR();
289 }
2166f0fa
SK
290
291 myHighlightColor->rgb[0] = R;
292 myHighlightColor->rgb[1] = G;
293 myHighlightColor->rgb[2] = B;
294 myHighlightColor->rgb[3] = 1.F;
295}
296
4269bd1b 297// =======================================================================
298// function : ClearHighlightColor
299// purpose :
300// =======================================================================
5e27df78 301void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 302{
5e27df78 303 ClearHighlightBox(theGlCtx);
304 delete myHighlightColor;
305 myHighlightColor = NULL;
2166f0fa
SK
306}
307
4269bd1b 308// =======================================================================
309// function : Connect
310// purpose :
311// =======================================================================
2166f0fa
SK
312void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
313{
314 Disconnect (AStructure);
315 myConnected.Append(AStructure);
316}
317
4269bd1b 318// =======================================================================
319// function : Disconnect
320// purpose :
321// =======================================================================
2166f0fa
SK
322void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
323{
324 OpenGl_ListOfStructure::Iterator its(myConnected);
325 while (its.More())
326 {
327 // Check for the given structure
328 if (its.Value() == AStructure)
329 {
330 myConnected.Remove(its);
331 return;
332 }
333 its.Next();
334 }
335}
336
4269bd1b 337// =======================================================================
338// function : AddGroup
339// purpose :
340// =======================================================================
2166f0fa
SK
341OpenGl_Group * OpenGl_Structure::AddGroup ()
342{
343 // Create new group
344 OpenGl_Group *g = new OpenGl_Group;
345 myGroups.Append(g);
346 return g;
347}
348
4269bd1b 349// =======================================================================
350// function : RemoveGroup
351// purpose :
352// =======================================================================
5e27df78 353void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
354 const OpenGl_Group* theGroup)
2166f0fa 355{
5e27df78 356 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
2166f0fa
SK
357 {
358 // Check for the given group
5e27df78 359 if (anIter.Value() == theGroup)
2166f0fa
SK
360 {
361 // Delete object
5e27df78 362 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
363 myGroups.Remove (anIter);
2166f0fa
SK
364 return;
365 }
2166f0fa
SK
366 }
367}
368
4269bd1b 369// =======================================================================
370// function : Clear
371// purpose :
372// =======================================================================
5e27df78 373void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 374{
5e27df78 375 // Release groups
376 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
2166f0fa
SK
377 {
378 // Delete objects
5e27df78 379 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
2166f0fa
SK
380 }
381 myGroups.Clear();
382}
383
4269bd1b 384// =======================================================================
385// function : Render
386// purpose :
387// =======================================================================
2166f0fa
SK
388void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
389{
390 // Process the structure only if visible
391 if ( myNamedStatus & OPENGL_NS_HIDE )
392 return;
393
394 // Render named status
395 const Standard_Integer named_status = AWorkspace->NamedStatus;
396 AWorkspace->NamedStatus |= myNamedStatus;
397
398 // Is rendering in ADD or IMMEDIATE mode?
399 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
400
401 // Apply local transformation
402 GLint matrix_mode = 0;
403 const OpenGl_Matrix *local_trsf = NULL;
404 if (myTransformation)
405 {
406 if (isImmediate)
407 {
408 float mat16[16];
409 call_util_transpose_mat (mat16, myTransformation->mat);
410 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
411 glMatrixMode (GL_MODELVIEW);
412 glPushMatrix ();
413 glScalef (1.F, 1.F, 1.F);
414 glMultMatrixf (mat16);
415 }
416 else
417 {
418 glMatrixMode (GL_MODELVIEW);
419 glPushMatrix();
420
421 local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
422 }
423 }
424
425 // Apply transform persistence
426 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
427 if ( myTransPers && myTransPers->mode != 0 )
428 {
429 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
430 }
431
2166f0fa
SK
432 // Apply aspects
433 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
434 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
435 const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
436 const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
437 if (myAspectLine)
438 AWorkspace->SetAspectLine(myAspectLine);
439 if (myAspectFace)
440 AWorkspace->SetAspectFace(myAspectFace);
441 if (myAspectMarker)
442 AWorkspace->SetAspectMarker(myAspectMarker);
443 if (myAspectText)
444 AWorkspace->SetAspectText(myAspectText);
445
446 // Apply highlight box
447 if (myHighlightBox)
448 myHighlightBox->Render( AWorkspace );
449
450 // Apply highlight color
451 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
452 if (myHighlightColor)
453 AWorkspace->HighlightColor = myHighlightColor;
454
455 // Render connected structures
456 OpenGl_ListOfStructure::Iterator its(myConnected);
457 while (its.More())
458 {
459 its.Value()->Render(AWorkspace);
460 its.Next();
461 }
462
4269bd1b 463 // Set up plane equations for non-structure transformed global model-view matrix
464 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
465
b859a34d 466 // List of planes to be applied to context state
467 Handle(Graphic3d_SetOfHClipPlane) aUserPlanes;
468
469 // Collect clipping planes of structure scope
470 if (!myClipPlanes.IsEmpty())
4269bd1b 471 {
b859a34d 472 Graphic3d_SetOfHClipPlane::Iterator aClippingIt (myClipPlanes);
473 for (; aClippingIt.More(); aClippingIt.Next())
474 {
475 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
476 if (!aClipPlane->IsOn())
477 {
478 continue;
479 }
480
481 if (aUserPlanes.IsNull())
482 {
483 aUserPlanes = new Graphic3d_SetOfHClipPlane();
484 }
485
486 aUserPlanes->Add (aClipPlane);
487 }
4269bd1b 488 }
489
b859a34d 490 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
4269bd1b 491 {
b859a34d 492 // add planes at loaded view matrix state
493 aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
4269bd1b 494 }
495
2166f0fa
SK
496 // Render groups
497 OpenGl_ListOfGroup::Iterator itg(myGroups);
498 while (itg.More())
499 {
500 itg.Value()->Render(AWorkspace);
501 itg.Next();
502 }
503
b859a34d 504 // Render capping for structure groups
505 if (!aContext->Clipping().Planes().IsEmpty())
506 {
507 OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
508 }
4269bd1b 509
b859a34d 510 // Revert structure clippings
511 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
4269bd1b 512 {
b859a34d 513 aContext->ChangeClipping().Remove (*aUserPlanes);
4269bd1b 514 }
515
2166f0fa
SK
516 // Restore highlight color
517 AWorkspace->HighlightColor = highlight_color;
518
519 // Restore aspects
520 AWorkspace->SetAspectLine(aspect_line);
521 AWorkspace->SetAspectFace(aspect_face);
522 AWorkspace->SetAspectMarker(aspect_marker);
523 AWorkspace->SetAspectText(aspect_text);
524
525 // Restore transform persistence
526 if ( myTransPers && myTransPers->mode != 0 )
527 {
528 AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
529 }
530
531 // Restore local transformation
532 if (myTransformation)
533 {
534 if (isImmediate)
535 {
536 glPopMatrix ();
537 glMatrixMode (matrix_mode);
538 }
539 else
540 {
541 AWorkspace->SetStructureMatrix(local_trsf);
542
543 glMatrixMode (GL_MODELVIEW);
544 glPopMatrix();
545 }
546 }
547
548 // Restore named status
549 AWorkspace->NamedStatus = named_status;
550}
551
5e27df78 552// =======================================================================
553// function : Release
554// purpose :
555// =======================================================================
556void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
557{
558 // Release groups
559 Clear (theGlCtx);
560 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
561 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
562 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
563 OpenGl_Element::Destroy (theGlCtx, myAspectText);
564 ClearHighlightColor (theGlCtx);
565}
566
dd8a4ce9 567// =======================================================================
568// function : ReleaseGlResources
569// purpose :
570// =======================================================================
571void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
572{
573 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
574 {
575 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
576 if (aGroup != NULL)
577 {
578 aGroup->Release (theGlCtx);
579 }
580 }
581 if (myAspectLine != NULL)
582 {
583 myAspectLine->Release (theGlCtx);
584 }
585 if (myAspectFace != NULL)
586 {
587 myAspectFace->Release (theGlCtx);
588 }
589 if (myAspectMarker != NULL)
590 {
591 myAspectMarker->Release (theGlCtx);
592 }
593 if (myAspectText != NULL)
594 {
595 myAspectText->Release (theGlCtx);
596 }
597 if (myHighlightBox != NULL)
598 {
599 myHighlightBox->Release (theGlCtx);
600 }
601}
602
59f45b7c 603//=======================================================================
604//function : SetZLayer
bf75be98 605//purpose :
59f45b7c 606//=======================================================================
59f45b7c 607void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
608{
609 myZLayer = theLayerIndex;
610}
611
612//=======================================================================
613//function : GetZLayer
bf75be98 614//purpose :
59f45b7c 615//=======================================================================
59f45b7c 616Standard_Integer OpenGl_Structure::GetZLayer () const
617{
618 return myZLayer;
619}