0024288: Provide flipping text for AIS_Dimensions
[occt.git] / src / OpenGl / OpenGl_Group.cxx
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
20
21 #ifdef HAVE_CONFIG_H
22   #include <config.h>
23 #endif
24
25 #include <OpenGl_Group.hxx>
26 #include <OpenGl_PrimitiveArray.hxx>
27 #include <OpenGl_Structure.hxx>
28 #include <OpenGl_Workspace.hxx>
29
30 // =======================================================================
31 // function : OpenGl_Group
32 // purpose  :
33 // =======================================================================
34 #ifndef HAVE_OPENCL
35 OpenGl_Group::OpenGl_Group()
36 #else
37 OpenGl_Group::OpenGl_Group (const OpenGl_Structure* theAncestorStructure)
38 #endif
39 : myAspectLine(NULL),
40   myAspectFace(NULL),
41   myAspectMarker(NULL),
42   myAspectText(NULL),
43   myFirst(NULL),
44   myLast(NULL)
45 {
46 #ifdef HAVE_OPENCL
47   myAncestorStructure = theAncestorStructure;
48   myIsRaytracable = Standard_False;
49   myModificationState = 0; // initial state
50 #endif
51 }
52
53 // =======================================================================
54 // function : ~OpenGl_Group
55 // purpose  :
56 // =======================================================================
57 OpenGl_Group::~OpenGl_Group()
58 {
59   Release (Handle(OpenGl_Context)());
60 }
61
62 // =======================================================================
63 // function : SetAspectLine
64 // purpose  :
65 // =======================================================================
66 void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theAspect,
67                                   const Standard_Boolean theIsGlobal)
68 {
69   if (theIsGlobal || myFirst == NULL)
70   {
71     if (myAspectLine == NULL)
72     {
73       myAspectLine = new OpenGl_AspectLine();
74     }
75     myAspectLine->SetAspect (theAspect);
76   }
77   else
78   {
79     OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
80     anAspectLine->SetAspect (theAspect);
81     AddElement (TelNil/*TelAspectLine*/, anAspectLine);
82   }
83 }
84
85 // =======================================================================
86 // function : SetAspectFace
87 // purpose  :
88 // =======================================================================
89 void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect,
90                                   const Standard_Boolean          theIsGlobal)
91 {
92   if (theIsGlobal || myFirst == NULL)
93   {
94     if (myAspectFace == NULL)
95     {
96       myAspectFace = new OpenGl_AspectFace();
97     }
98     myAspectFace->SetAspect (theAspect);
99   }
100   else
101   {
102     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
103     anAspectFace->SetAspect (theAspect);
104     AddElement (TelNil/*TelAspectFace*/, anAspectFace);
105   }
106
107 #ifdef HAVE_OPENCL
108   if (myIsRaytracable)
109   {
110     myModificationState++;
111
112     if (myAncestorStructure != NULL)
113     {
114       myAncestorStructure->UpdateStateWithAncestorStructures();
115     }
116   }
117 #endif
118 }
119
120 // =======================================================================
121 // function : SetAspectMarker
122 // purpose  :
123 // =======================================================================
124 void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect,
125                                     const Standard_Boolean theIsGlobal)
126 {
127   if (theIsGlobal || myFirst == NULL)
128   {
129     if (myAspectMarker == NULL)
130     {
131       myAspectMarker = new OpenGl_AspectMarker();
132     }
133     myAspectMarker->SetAspect (theAspect);
134   }
135   else
136   {
137     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
138     anAspectMarker->SetAspect (theAspect);
139     AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
140   }
141 }
142
143 // =======================================================================
144 // function : SetAspectText
145 // purpose  :
146 // =======================================================================
147 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theAspect,
148                                   const Standard_Boolean theIsGlobal)
149 {
150   if (theIsGlobal || myFirst == NULL)
151   {
152     if (myAspectText == NULL)
153     {
154       myAspectText = new OpenGl_AspectText();
155     }
156     myAspectText->SetAspect (theAspect);
157   }
158   else
159   {
160     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
161     anAspectText->SetAspect (theAspect);
162     AddElement ( TelNil/*TelAspectText*/, anAspectText);
163   }
164 }
165
166 // =======================================================================
167 // function : AddElement
168 // purpose  :
169 // =======================================================================
170 void OpenGl_Group::AddElement (const TelType theType, OpenGl_Element *theElem)
171 {
172   OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
173
174   aNode->type = theType;
175   aNode->elem = theElem;
176   aNode->next = NULL;
177   (myLast? myLast->next : myFirst) = aNode;
178   myLast = aNode;
179
180 #ifdef HAVE_OPENCL
181   if (OpenGl_Raytrace::IsRaytracedElement (aNode))
182   {
183     myModificationState++;
184     myIsRaytracable = Standard_True;
185
186     if (myAncestorStructure != NULL)
187     {
188       myAncestorStructure->UpdateStateWithAncestorStructures();
189       myAncestorStructure->SetRaytracableWithAncestorStructures();
190     }
191   }
192 #endif
193 }
194
195 // =======================================================================
196 // function : Render
197 // purpose  :
198 // =======================================================================
199 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
200 {
201   // Is rendering in ADD or IMMEDIATE mode?
202   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
203   const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
204
205   // Setup aspects
206   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
207   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
208   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
209   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
210   Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
211   Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
212   Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
213   Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
214
215   // Render group elements
216   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
217   {
218     switch (aNodeIter->type)
219     {
220       case TelMarker:
221       case TelMarkerSet:
222       case TelText:
223       {
224         glDisable (GL_LIGHTING);
225         if (isImmediate)
226         {
227           glDepthMask (GL_FALSE);
228         }
229
230         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
231         break;
232       }
233       default:
234       {
235         aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
236         break;
237       }
238     }
239   }
240
241   // Restore aspects
242   if (isLineSet)
243     theWorkspace->SetAspectLine (aBackAspectLine);
244   if (isFaceSet)
245     theWorkspace->SetAspectFace (aBackAspectFace);
246   if (isMarkerSet)
247     theWorkspace->SetAspectMarker (aBackAspectMarker);
248   if (isTextSet)
249     theWorkspace->SetAspectText (aBackAspectText);
250 }
251
252 // =======================================================================
253 // function : Release
254 // purpose  :
255 // =======================================================================
256 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
257 {
258   // Delete elements
259   while (myFirst != NULL)
260   {
261     OpenGl_ElementNode* aNext = myFirst->next;
262     OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
263     delete myFirst;
264     myFirst = aNext;
265   }
266   myLast = NULL;
267
268   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
269   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
270   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
271   OpenGl_Element::Destroy (theGlCtx, myAspectText);
272 }