0026641: Visualization, TKOpenGl - handle correctly transformation persistence within...
[occt.git] / src / OpenGl / OpenGl_Group.cxx
CommitLineData
b311480e 1// Created on: 2011-08-01
2// Created by: Sergey ZERCHANINOV
973c2be1 3// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
2166f0fa 15
e276548b 16#include <OpenGl_Group.hxx>
b64d84be 17
18#include <OpenGl_GraphicDriver.hxx>
19#include <OpenGl_Flipper.hxx>
2166f0fa 20#include <OpenGl_PrimitiveArray.hxx>
c357e426 21#include <OpenGl_SceneGeometry.hxx>
b64d84be 22#include <OpenGl_StencilTest.hxx>
e276548b 23#include <OpenGl_Structure.hxx>
b64d84be 24#include <OpenGl_Text.hxx>
bf75be98 25#include <OpenGl_Workspace.hxx>
2166f0fa 26
b64d84be 27#include <Graphic3d_ArrayOfPrimitives.hxx>
b64d84be 28#include <Graphic3d_GroupDefinitionError.hxx>
29
b64d84be 30
92efcf78 31IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group)
32
4269bd1b 33// =======================================================================
34// function : OpenGl_Group
35// purpose :
36// =======================================================================
b64d84be 37OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
38: Graphic3d_Group (theStruct),
39 myAspectLine(NULL),
e276548b 40 myAspectFace(NULL),
41 myAspectMarker(NULL),
42 myAspectText(NULL),
43 myFirst(NULL),
b64d84be 44 myLast(NULL),
d4aaad5b 45 myIsRaytracable (Standard_False)
2166f0fa 46{
b64d84be 47 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
c04c30b3 48 if (aStruct.IsNull())
b64d84be 49 {
50 Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!");
51 }
2166f0fa
SK
52}
53
4269bd1b 54// =======================================================================
55// function : ~OpenGl_Group
56// purpose :
57// =======================================================================
2166f0fa
SK
58OpenGl_Group::~OpenGl_Group()
59{
5e27df78 60 Release (Handle(OpenGl_Context)());
2166f0fa
SK
61}
62
4269bd1b 63// =======================================================================
b64d84be 64// function : UpdateAspectLine
4269bd1b 65// purpose :
66// =======================================================================
b64d84be 67void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal)
2166f0fa 68{
b64d84be 69 if (!ContextLine.IsDef)
70 {
71 return;
72 }
73
2166f0fa
SK
74 if (theIsGlobal || myFirst == NULL)
75 {
76 if (myAspectLine == NULL)
fd4a6963 77 {
2166f0fa 78 myAspectLine = new OpenGl_AspectLine();
fd4a6963 79 }
b64d84be 80 myAspectLine->SetAspect (ContextLine);
2166f0fa
SK
81 }
82 else
83 {
84 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
b64d84be 85 anAspectLine->SetAspect (ContextLine);
5322131b 86 AddElement (anAspectLine);
2166f0fa
SK
87 }
88}
89
4269bd1b 90// =======================================================================
b64d84be 91// function : UpdateAspectFace
4269bd1b 92// purpose :
93// =======================================================================
b64d84be 94void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal)
2166f0fa 95{
b64d84be 96 if (!ContextFillArea.IsDef)
97 {
98 return;
99 }
100
2166f0fa
SK
101 if (theIsGlobal || myFirst == NULL)
102 {
103 if (myAspectFace == NULL)
bf75be98 104 {
2166f0fa 105 myAspectFace = new OpenGl_AspectFace();
bf75be98 106 }
b64d84be 107 myAspectFace->SetAspect (ContextFillArea);
2166f0fa
SK
108 }
109 else
110 {
111 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
b64d84be 112 anAspectFace->SetAspect (ContextFillArea);
5322131b 113 AddElement (anAspectFace);
2166f0fa 114 }
e276548b 115
e276548b 116 if (myIsRaytracable)
117 {
b64d84be 118 OpenGl_Structure* aStruct = GlStruct();
119 if (aStruct != NULL)
e276548b 120 {
d4aaad5b 121 aStruct->UpdateStateIfRaytracable (Standard_False);
e276548b 122 }
123 }
2166f0fa
SK
124}
125
4269bd1b 126// =======================================================================
b64d84be 127// function : UpdateAspectMarker
4269bd1b 128// purpose :
129// =======================================================================
b64d84be 130void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal)
2166f0fa 131{
b64d84be 132 if (!ContextMarker.IsDef)
133 {
134 return;
135 }
136
2166f0fa
SK
137 if (theIsGlobal || myFirst == NULL)
138 {
139 if (myAspectMarker == NULL)
a577aaab 140 {
2166f0fa 141 myAspectMarker = new OpenGl_AspectMarker();
a577aaab 142 }
b64d84be 143 myAspectMarker->SetAspect (ContextMarker);
2166f0fa
SK
144 }
145 else
146 {
147 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
b64d84be 148 anAspectMarker->SetAspect (ContextMarker);
5322131b 149 AddElement (anAspectMarker);
2166f0fa
SK
150 }
151}
152
4269bd1b 153// =======================================================================
b64d84be 154// function : UpdateAspectText
4269bd1b 155// purpose :
156// =======================================================================
b64d84be 157void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
2166f0fa 158{
b64d84be 159 if (!ContextText.IsDef)
160 {
161 return;
162 }
163
2166f0fa
SK
164 if (theIsGlobal || myFirst == NULL)
165 {
166 if (myAspectText == NULL)
fd4a6963 167 {
2166f0fa 168 myAspectText = new OpenGl_AspectText();
fd4a6963 169 }
b64d84be 170 myAspectText->SetAspect (ContextText);
2166f0fa
SK
171 }
172 else
173 {
174 OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
b64d84be 175 anAspectText->SetAspect (ContextText);
5322131b 176 AddElement (anAspectText);
2166f0fa
SK
177 }
178}
179
b64d84be 180// =======================================================================
181// function : AddPrimitiveArray
182// purpose :
183// =======================================================================
871fa103 184void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
185 const Handle(Graphic3d_IndexBuffer)& theIndices,
186 const Handle(Graphic3d_Buffer)& theAttribs,
187 const Handle(Graphic3d_BoundBuffer)& theBounds,
188 const Standard_Boolean theToEvalMinMax)
b64d84be 189{
190 if (IsDeleted()
871fa103 191 || theAttribs.IsNull())
b64d84be 192 {
193 return;
194 }
195
8d3f219f 196 OpenGl_Structure* aStruct = GlStruct();
197 const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
198
199 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
b64d84be 200 AddElement (anArray);
201
871fa103 202 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
b64d84be 203}
204
205// =======================================================================
206// function : Text
207// purpose :
208// =======================================================================
209void OpenGl_Group::Text (const Standard_CString theTextUtf,
210 const Graphic3d_Vertex& thePoint,
211 const Standard_Real theHeight,
212 const Quantity_PlaneAngle theAngle,
213 const Graphic3d_TextPath theTp,
214 const Graphic3d_HorizontalTextAlignment theHta,
215 const Graphic3d_VerticalTextAlignment theVta,
216 const Standard_Boolean theToEvalMinMax)
217{
218 if (IsDeleted())
219 {
220 return;
221 }
222
223 OpenGl_TextParam aParams;
224 OpenGl_Structure* aStruct = GlStruct();
225 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
226 aParams.HAlign = theHta;
227 aParams.VAlign = theVta;
228 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
229 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
230 AddElement (aText);
231 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
232 theTp, theHta, theVta, theToEvalMinMax);
233}
234
ce01ec26 235// =======================================================================
236// function : Text
237// purpose :
238// =======================================================================
239void OpenGl_Group::Text (const Standard_CString theTextUtf,
240 const gp_Ax2& theOrientation,
241 const Standard_Real theHeight,
242 const Quantity_PlaneAngle theAngle,
243 const Graphic3d_TextPath theTp,
244 const Graphic3d_HorizontalTextAlignment theHTA,
245 const Graphic3d_VerticalTextAlignment theVTA,
3f1eb0ab 246 const Standard_Boolean theToEvalMinMax,
247 const Standard_Boolean theHasOwnAnchor)
ce01ec26 248{
249 if (IsDeleted())
250 {
251 return;
252 }
253
254 OpenGl_TextParam aParams;
255 OpenGl_Structure* aStruct = GlStruct();
256
257 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
258 aParams.HAlign = theHTA;
259 aParams.VAlign = theVTA;
260
3f1eb0ab 261 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, theOrientation, aParams, theHasOwnAnchor != Standard_False);
ce01ec26 262
263 AddElement (aText);
264
265 Graphic3d_Group::Text (theTextUtf,
266 theOrientation,
267 theHeight,
268 theAngle,
269 theTp,
270 theHTA,
271 theVTA,
3f1eb0ab 272 theToEvalMinMax,
273 theHasOwnAnchor);
ce01ec26 274
275}
276
b64d84be 277// =======================================================================
278// function : SetFlippingOptions
279// purpose :
280// =======================================================================
281void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
282 const gp_Ax2& theRefPlane)
283{
284 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
285 aFlipper->SetOptions (theIsEnabled);
286 AddElement (aFlipper);
287}
288
289// =======================================================================
290// function : SetStencilTestOptions
291// purpose :
292// =======================================================================
293void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
294{
295 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
296 aStencilTest->SetOptions (theIsEnabled);
297 AddElement (aStencilTest);
298}
299
4269bd1b 300// =======================================================================
301// function : AddElement
302// purpose :
303// =======================================================================
5322131b 304void OpenGl_Group::AddElement (OpenGl_Element* theElem)
2166f0fa 305{
e276548b 306 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
307
e276548b 308 aNode->elem = theElem;
309 aNode->next = NULL;
310 (myLast? myLast->next : myFirst) = aNode;
311 myLast = aNode;
312
e276548b 313 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
314 {
e276548b 315 myIsRaytracable = Standard_True;
2166f0fa 316
b64d84be 317 OpenGl_Structure* aStruct = GlStruct();
318 if (aStruct != NULL)
e276548b 319 {
d4aaad5b 320 aStruct->UpdateStateIfRaytracable (Standard_False);
e276548b 321 }
322 }
2166f0fa
SK
323}
324
4269bd1b 325// =======================================================================
326// function : Render
327// purpose :
328// =======================================================================
bf75be98 329void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
2166f0fa
SK
330{
331 // Is rendering in ADD or IMMEDIATE mode?
4269bd1b 332 const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
2166f0fa
SK
333
334 // Setup aspects
f9ba5c4d 335 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine();
336 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace();
337 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker();
338 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText();
4269bd1b 339 Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
340 Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
341 Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
342 Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
2166f0fa
SK
343
344 // Render group elements
bf75be98 345 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
2166f0fa 346 {
5322131b 347 aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
2166f0fa
SK
348 }
349
350 // Restore aspects
4269bd1b 351 if (isLineSet)
352 theWorkspace->SetAspectLine (aBackAspectLine);
353 if (isFaceSet)
354 theWorkspace->SetAspectFace (aBackAspectFace);
355 if (isMarkerSet)
356 theWorkspace->SetAspectMarker (aBackAspectMarker);
357 if (isTextSet)
358 theWorkspace->SetAspectText (aBackAspectText);
2166f0fa
SK
359}
360
b64d84be 361// =======================================================================
362// function : Clear
363// purpose :
364// =======================================================================
365void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
366{
367 if (IsDeleted())
368 {
369 return;
370 }
371
372 OpenGl_Structure* aStruct = GlStruct();
373 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
374
375 Release (aCtx);
376 Graphic3d_Group::Clear (theToUpdateStructureMgr);
d4aaad5b 377
378 myIsRaytracable = Standard_False;
b64d84be 379}
380
4269bd1b 381// =======================================================================
382// function : Release
383// purpose :
384// =======================================================================
5e27df78 385void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
386{
387 // Delete elements
388 while (myFirst != NULL)
389 {
390 OpenGl_ElementNode* aNext = myFirst->next;
10b9c7df 391 OpenGl_Element::Destroy (theGlCtx.operator->(), myFirst->elem);
5e27df78 392 delete myFirst;
393 myFirst = aNext;
394 }
395 myLast = NULL;
396
10b9c7df 397 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
398 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
399 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
400 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
5e27df78 401}