0024228: TKOpenGL - destroy GL context at view close
[occt.git] / src / OpenGl / OpenGl_CappingPlaneResource.cxx
1 // Created on: 2013-08-15
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013 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
20 #include <OpenGl_CappingPlaneResource.hxx>
21 #include <OpenGl_Context.hxx>
22 #include <OpenGl_Vec.hxx>
23 #include <Precision.hxx>
24
25 IMPLEMENT_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
26 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource, OpenGl_Resource)
27
28 // =======================================================================
29 // function : OpenGl_CappingPlaneResource
30 // purpose  :
31 // =======================================================================
32 OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
33 : myOrientation (OpenGl_IdentityMatrix),
34   myAspect (NULL),
35   myPlaneRoot (thePlane),
36   myEquationMod (0),
37   myAspectMod (0)
38 {}
39
40 // =======================================================================
41 // function : OpenGl_CappingPlaneResource
42 // purpose  :
43 // =======================================================================
44 OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
45 {
46   Release (NULL);
47 }
48
49 // =======================================================================
50 // function : Update
51 // purpose  :
52 // =======================================================================
53 void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext)
54 {
55   UpdateTransform();
56   UpdateAspect (theContext);
57 }
58
59 // =======================================================================
60 // function : Release
61 // purpose  :
62 // =======================================================================
63 void OpenGl_CappingPlaneResource::Release (const OpenGl_Context* theContext)
64 {
65   OpenGl_Element::Destroy (theContext, myAspect);
66   myEquationMod = 0;
67   myAspectMod   = 0;
68 }
69
70 // =======================================================================
71 // function : UpdateAspect
72 // purpose  :
73 // =======================================================================
74 void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext)
75 {
76   Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect();
77   if (myAspect != NULL && !aCappingAsp.IsNull())
78   {
79     if (myAspectMod == myPlaneRoot->MCountAspect())
80       return; // noting to update
81     
82     myAspect->SetAspect (aCappingAsp);
83     myAspectMod = myPlaneRoot->MCountAspect();
84     return;
85   }
86
87   // no more used
88   if (myAspect != NULL && aCappingAsp.IsNull())
89   {
90     OpenGl_Element::Destroy (theContext, myAspect);
91     myAspectMod = myPlaneRoot->MCountAspect();
92     return;
93   }
94
95   // first created
96   if (myAspect == NULL && !aCappingAsp.IsNull())
97   {
98     myAspect = new OpenGl_AspectFace();
99     myAspect->SetAspect (aCappingAsp);
100     myAspectMod = myPlaneRoot->MCountAspect();
101   }
102 }
103
104 // =======================================================================
105 // function : UpdateTransform
106 // purpose  :
107 // =======================================================================
108 void OpenGl_CappingPlaneResource::UpdateTransform()
109 {
110   const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
111   if (myEquationMod == myPlaneRoot->MCountEquation())
112   {
113     return; // nothing to update
114   }
115
116   // re-evaluate infinite plane transformation matrix
117   Standard_ShortReal N[3] = 
118     { (Standard_ShortReal)anEquation[0],
119       (Standard_ShortReal)anEquation[1],
120       (Standard_ShortReal)anEquation[2] };
121
122   Standard_ShortReal T[3] = 
123     { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
124       (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
125       (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
126
127   Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
128   Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
129
130   // project plane normal onto OX to find left vector
131   Standard_ShortReal aConfusion = (Standard_ShortReal)Precision::Confusion();
132   Standard_ShortReal aProjLen = 
133     sqrt (  (Standard_ShortReal)(anEquation[0] * anEquation[0])
134           + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
135   if (aProjLen < aConfusion)
136   {
137     L[0] = 1.0f;
138   }
139   else
140   {
141     L[0] =  N[2] / aProjLen;
142     L[2] = -N[0] / aProjLen;
143   }
144
145   // (-aLeft) x aNorm
146   F[0] = (-L[1])*N[2] - (-L[2])*N[1];
147   F[1] = (-L[2])*N[0] - (-L[0])*N[2];
148   F[2] = (-L[0])*N[1] - (-L[1])*N[0];
149
150   myOrientation.mat[0][0] = L[0];
151   myOrientation.mat[0][1] = L[1];
152   myOrientation.mat[0][2] = L[2];
153   myOrientation.mat[0][3] = 0.0f;
154
155   myOrientation.mat[1][0] = N[0];
156   myOrientation.mat[1][1] = N[1];
157   myOrientation.mat[1][2] = N[2];
158   myOrientation.mat[1][3] = 0.0f;
159
160   myOrientation.mat[2][0] = F[0];
161   myOrientation.mat[2][1] = F[1];
162   myOrientation.mat[2][2] = F[2];
163   myOrientation.mat[2][3] = 0.0f;
164
165   myOrientation.mat[3][0] = T[0];
166   myOrientation.mat[3][1] = T[1];
167   myOrientation.mat[3][2] = T[2];
168   myOrientation.mat[3][3] = 1.0f;
169
170   myEquationMod = myPlaneRoot->MCountEquation();
171 }