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