0024752: Visualization - inherit OpenGl_Group from Graphic3d_Group
[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#ifdef HAVE_CONFIG_H
17 #include <config.h>
18#endif
19
20#include <OpenGl_Group.hxx>
b64d84be 21
22#include <OpenGl_GraphicDriver.hxx>
23#include <OpenGl_Flipper.hxx>
2166f0fa 24#include <OpenGl_PrimitiveArray.hxx>
b64d84be 25#include <OpenGl_StencilTest.hxx>
e276548b 26#include <OpenGl_Structure.hxx>
b64d84be 27#include <OpenGl_Text.hxx>
bf75be98 28#include <OpenGl_Workspace.hxx>
2166f0fa 29
b64d84be 30#include <Graphic3d_ArrayOfPrimitives.hxx>
31#include <Graphic3d_CUserDraw.hxx>
32#include <Graphic3d_GroupDefinitionError.hxx>
33
34IMPLEMENT_STANDARD_HANDLE (OpenGl_Group, Graphic3d_Group)
35IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group, Graphic3d_Group)
36
4269bd1b 37// =======================================================================
38// function : OpenGl_Group
39// purpose :
40// =======================================================================
b64d84be 41OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
42: Graphic3d_Group (theStruct),
43 myAspectLine(NULL),
e276548b 44 myAspectFace(NULL),
45 myAspectMarker(NULL),
46 myAspectText(NULL),
47 myFirst(NULL),
b64d84be 48 myLast(NULL),
49 myIsRaytracable (Standard_False),
50 myModificationState (0)
2166f0fa 51{
b64d84be 52 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
53 if (aStruct == NULL)
54 {
55 Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!");
56 }
2166f0fa
SK
57}
58
4269bd1b 59// =======================================================================
60// function : ~OpenGl_Group
61// purpose :
62// =======================================================================
2166f0fa
SK
63OpenGl_Group::~OpenGl_Group()
64{
5e27df78 65 Release (Handle(OpenGl_Context)());
2166f0fa
SK
66}
67
4269bd1b 68// =======================================================================
b64d84be 69// function : UpdateAspectLine
4269bd1b 70// purpose :
71// =======================================================================
b64d84be 72void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal)
2166f0fa 73{
b64d84be 74 if (!ContextLine.IsDef)
75 {
76 return;
77 }
78
2166f0fa
SK
79 if (theIsGlobal || myFirst == NULL)
80 {
81 if (myAspectLine == NULL)
fd4a6963 82 {
2166f0fa 83 myAspectLine = new OpenGl_AspectLine();
fd4a6963 84 }
b64d84be 85 myAspectLine->SetAspect (ContextLine);
2166f0fa
SK
86 }
87 else
88 {
89 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
b64d84be 90 anAspectLine->SetAspect (ContextLine);
5322131b 91 AddElement (anAspectLine);
2166f0fa
SK
92 }
93}
94
4269bd1b 95// =======================================================================
b64d84be 96// function : UpdateAspectFace
4269bd1b 97// purpose :
98// =======================================================================
b64d84be 99void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal)
2166f0fa 100{
b64d84be 101 if (!ContextFillArea.IsDef)
102 {
103 return;
104 }
105
2166f0fa
SK
106 if (theIsGlobal || myFirst == NULL)
107 {
108 if (myAspectFace == NULL)
bf75be98 109 {
2166f0fa 110 myAspectFace = new OpenGl_AspectFace();
bf75be98 111 }
b64d84be 112 myAspectFace->SetAspect (ContextFillArea);
2166f0fa
SK
113 }
114 else
115 {
116 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
b64d84be 117 anAspectFace->SetAspect (ContextFillArea);
5322131b 118 AddElement (anAspectFace);
2166f0fa 119 }
e276548b 120
121#ifdef HAVE_OPENCL
122 if (myIsRaytracable)
123 {
b64d84be 124 ++myModificationState;
125 OpenGl_Structure* aStruct = GlStruct();
126 if (aStruct != NULL)
e276548b 127 {
b64d84be 128 aStruct->UpdateStateWithAncestorStructures();
e276548b 129 }
130 }
131#endif
2166f0fa
SK
132}
133
4269bd1b 134// =======================================================================
b64d84be 135// function : UpdateAspectMarker
4269bd1b 136// purpose :
137// =======================================================================
b64d84be 138void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal)
2166f0fa 139{
b64d84be 140 if (!ContextMarker.IsDef)
141 {
142 return;
143 }
144
2166f0fa
SK
145 if (theIsGlobal || myFirst == NULL)
146 {
147 if (myAspectMarker == NULL)
a577aaab 148 {
2166f0fa 149 myAspectMarker = new OpenGl_AspectMarker();
a577aaab 150 }
b64d84be 151 myAspectMarker->SetAspect (ContextMarker);
2166f0fa
SK
152 }
153 else
154 {
155 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
b64d84be 156 anAspectMarker->SetAspect (ContextMarker);
5322131b 157 AddElement (anAspectMarker);
2166f0fa
SK
158 }
159}
160
4269bd1b 161// =======================================================================
b64d84be 162// function : UpdateAspectText
4269bd1b 163// purpose :
164// =======================================================================
b64d84be 165void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
2166f0fa 166{
b64d84be 167 if (!ContextText.IsDef)
168 {
169 return;
170 }
171
2166f0fa
SK
172 if (theIsGlobal || myFirst == NULL)
173 {
174 if (myAspectText == NULL)
fd4a6963 175 {
2166f0fa 176 myAspectText = new OpenGl_AspectText();
fd4a6963 177 }
b64d84be 178 myAspectText->SetAspect (ContextText);
2166f0fa
SK
179 }
180 else
181 {
182 OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
b64d84be 183 anAspectText->SetAspect (ContextText);
5322131b 184 AddElement (anAspectText);
2166f0fa
SK
185 }
186}
187
4269bd1b 188// =======================================================================
b64d84be 189// function : AddPrimitiveArray
190// purpose :
191// =======================================================================
192void OpenGl_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
193 const Standard_Boolean theToEvalMinMax)
194{
195 if (IsDeleted()
196 || !thePrim->IsValid())
197 {
198 return;
199 }
200
201 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray ((CALL_DEF_PARRAY *)thePrim->Array());
202 AddElement (anArray);
203
204 Graphic3d_Group::AddPrimitiveArray (thePrim, theToEvalMinMax);
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
303#ifdef HAVE_OPENCL
304 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
305 {
306 myModificationState++;
307 myIsRaytracable = Standard_True;
2166f0fa 308
b64d84be 309 OpenGl_Structure* aStruct = GlStruct();
310 if (aStruct != NULL)
e276548b 311 {
b64d84be 312 aStruct->UpdateStateWithAncestorStructures();
313 aStruct->SetRaytracableWithAncestorStructures();
e276548b 314 }
315 }
316#endif
2166f0fa
SK
317}
318
4269bd1b 319// =======================================================================
320// function : Render
321// purpose :
322// =======================================================================
bf75be98 323void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
2166f0fa
SK
324{
325 // Is rendering in ADD or IMMEDIATE mode?
4269bd1b 326 const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
2166f0fa
SK
327
328 // Setup aspects
bf75be98 329 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
330 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
331 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
332 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
4269bd1b 333 Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
334 Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
335 Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
336 Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
2166f0fa
SK
337
338 // Render group elements
bf75be98 339 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
2166f0fa 340 {
5322131b 341 aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
2166f0fa
SK
342 }
343
344 // Restore aspects
4269bd1b 345 if (isLineSet)
346 theWorkspace->SetAspectLine (aBackAspectLine);
347 if (isFaceSet)
348 theWorkspace->SetAspectFace (aBackAspectFace);
349 if (isMarkerSet)
350 theWorkspace->SetAspectMarker (aBackAspectMarker);
351 if (isTextSet)
352 theWorkspace->SetAspectText (aBackAspectText);
2166f0fa
SK
353}
354
4269bd1b 355// =======================================================================
b64d84be 356// function : Clear
357// purpose :
358// =======================================================================
359void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
360{
361 if (IsDeleted())
362 {
363 return;
364 }
365
366 OpenGl_Structure* aStruct = GlStruct();
367 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
368
369 Release (aCtx);
370 Graphic3d_Group::Clear (theToUpdateStructureMgr);
371}
372
373// =======================================================================
4269bd1b 374// function : Release
375// purpose :
376// =======================================================================
5e27df78 377void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
378{
379 // Delete elements
380 while (myFirst != NULL)
381 {
382 OpenGl_ElementNode* aNext = myFirst->next;
383 OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
384 delete myFirst;
385 myFirst = aNext;
386 }
387 myLast = NULL;
388
389 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
390 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
391 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
392 OpenGl_Element::Destroy (theGlCtx, myAspectText);
393}