0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / OpenGl / OpenGl_CappingPlaneResource.cxx
1 // Created on: 2013-08-15
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <NCollection_AlignedAllocator.hxx>
17 #include <OpenGl_CappingPlaneResource.hxx>
18 #include <OpenGl_Context.hxx>
19 #include <OpenGl_Vec.hxx>
20 #include <Precision.hxx>
21
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource,OpenGl_Resource)
23
24 namespace
25 {
26   //! 12 plane vertices, interleaved:
27   //!  - 4 floats, position
28   //!  - 4 floats, normal
29   //!  - 4 floats, UV texture coordinates
30   static const GLfloat THE_CAPPING_PLN_VERTS[12 * (4 + 4 + 4)] =
31   {
32     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
33     1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f,
34     0.0f, 0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
35
36     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
37     0.0f, 0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
38    -1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
39
40     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
41    -1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
42     0.0f, 0.0f,-1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f,
43
44     0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
45     0.0f, 0.0f,-1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f,
46     1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f
47   };
48
49   static const OpenGl_Matrix OpenGl_IdentityMatrix =
50   {
51     // mat[4][4]
52     { { 1.0f, 0.0f, 0.0f, 0.0f },
53       { 0.0f, 1.0f, 0.0f, 0.0f },
54       { 0.0f, 0.0f, 1.0f, 0.0f },
55       { 0.0f, 0.0f, 0.0f, 1.0f } }
56   };
57
58 }
59
60
61 // =======================================================================
62 // function : OpenGl_CappingPlaneResource
63 // purpose  :
64 // =======================================================================
65 OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
66 : myPrimitives  (NULL),
67   myOrientation (OpenGl_IdentityMatrix),
68   myAspect      (NULL),
69   myPlaneRoot   (thePlane),
70   myEquationMod ((unsigned int )-1),
71   myAspectMod   ((unsigned int )-1)
72 {
73   // Fill primitive array
74   Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
75   Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc);
76   Graphic3d_Attribute anAttribInfo[] =
77   {
78     { Graphic3d_TOA_POS,  Graphic3d_TOD_VEC4 },
79     { Graphic3d_TOA_NORM, Graphic3d_TOD_VEC4 },
80     { Graphic3d_TOA_UV,   Graphic3d_TOD_VEC4 }
81   };
82   if (anAttribs->Init (12, anAttribInfo, 3))
83   {
84     memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
85     myPrimitives.InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
86   }
87 }
88
89 // =======================================================================
90 // function : OpenGl_CappingPlaneResource
91 // purpose  :
92 // =======================================================================
93 OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
94 {
95   Release (NULL);
96 }
97
98 // =======================================================================
99 // function : Update
100 // purpose  :
101 // =======================================================================
102 void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& ,
103                                           const Handle(Graphic3d_AspectFillArea3d)& theObjAspect)
104 {
105   updateTransform();
106   updateAspect (theObjAspect);
107 }
108
109 // =======================================================================
110 // function : Release
111 // purpose  :
112 // =======================================================================
113 void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
114 {
115   OpenGl_Element::Destroy (theContext, myAspect);
116   myPrimitives.Release (theContext);
117   myEquationMod = (unsigned int )-1;
118   myAspectMod   = (unsigned int )-1;
119 }
120
121 // =======================================================================
122 // function : updateAspect
123 // purpose  :
124 // =======================================================================
125 void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_AspectFillArea3d)& theObjAspect)
126 {
127   if (myAspect == NULL)
128   {
129     myAspect = new OpenGl_AspectFace();
130     myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync
131   }
132
133   if (theObjAspect.IsNull())
134   {
135     if (myAspectMod != myPlaneRoot->MCountAspect())
136     {
137       myAspect->SetAspect (myPlaneRoot->CappingAspect());
138       myAspectMod = myPlaneRoot->MCountAspect();
139     }
140     return;
141   }
142
143   if (myFillAreaAspect.IsNull())
144   {
145     myFillAreaAspect = new Graphic3d_AspectFillArea3d();
146   }
147   if (myAspectMod != myPlaneRoot->MCountAspect())
148   {
149     *myFillAreaAspect = *myPlaneRoot->CappingAspect();
150   }
151
152   if (myPlaneRoot->ToUseObjectMaterial())
153   {
154     // only front material currently supported by capping rendering
155     myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial());
156     myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor());
157   }
158   if (myPlaneRoot->ToUseObjectTexture())
159   {
160     myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet());
161     if (theObjAspect->ToMapTexture())
162     {
163       myFillAreaAspect->SetTextureMapOn();
164     }
165     else
166     {
167       myFillAreaAspect->SetTextureMapOff();
168     }
169   }
170   if (myPlaneRoot->ToUseObjectShader())
171   {
172     myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram());
173   }
174
175   myAspect->SetAspect (myFillAreaAspect);
176 }
177
178 // =======================================================================
179 // function : updateTransform
180 // purpose  :
181 // =======================================================================
182 void OpenGl_CappingPlaneResource::updateTransform()
183 {
184   const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
185   if (myEquationMod == myPlaneRoot->MCountEquation())
186   {
187     return; // nothing to update
188   }
189
190   // re-evaluate infinite plane transformation matrix
191   Standard_ShortReal N[3] = 
192     { (Standard_ShortReal)anEquation[0],
193       (Standard_ShortReal)anEquation[1],
194       (Standard_ShortReal)anEquation[2] };
195
196   Standard_ShortReal T[3] = 
197     { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
198       (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
199       (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
200
201   Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
202   Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
203
204   // project plane normal onto OX to find left vector
205   Standard_ShortReal aProjLen = 
206     sqrt (  (Standard_ShortReal)(anEquation[0] * anEquation[0])
207           + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
208   if (aProjLen < ShortRealSmall())
209   {
210     L[0] = 1.0f;
211   }
212   else
213   {
214     L[0] =  N[2] / aProjLen;
215     L[2] = -N[0] / aProjLen;
216   }
217
218   // (-aLeft) x aNorm
219   F[0] = (-L[1])*N[2] - (-L[2])*N[1];
220   F[1] = (-L[2])*N[0] - (-L[0])*N[2];
221   F[2] = (-L[0])*N[1] - (-L[1])*N[0];
222
223   myOrientation.mat[0][0] = L[0];
224   myOrientation.mat[0][1] = L[1];
225   myOrientation.mat[0][2] = L[2];
226   myOrientation.mat[0][3] = 0.0f;
227
228   myOrientation.mat[1][0] = N[0];
229   myOrientation.mat[1][1] = N[1];
230   myOrientation.mat[1][2] = N[2];
231   myOrientation.mat[1][3] = 0.0f;
232
233   myOrientation.mat[2][0] = F[0];
234   myOrientation.mat[2][1] = F[1];
235   myOrientation.mat[2][2] = F[2];
236   myOrientation.mat[2][3] = 0.0f;
237
238   myOrientation.mat[3][0] = T[0];
239   myOrientation.mat[3][1] = T[1];
240   myOrientation.mat[3][2] = T[2];
241   myOrientation.mat[3][3] = 1.0f;
242
243   myEquationMod = myPlaneRoot->MCountEquation();
244 }