0029929: Visualization, V3d_View - make method ::FitMinMax() public
[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 {
9775fa61 50 throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!");
b64d84be 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// =======================================================================
b6472664 64// function : SetGroupPrimitivesAspect
4269bd1b 65// purpose :
66// =======================================================================
b6472664 67void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect)
2166f0fa 68{
b6472664 69 if (IsDeleted())
b64d84be 70 {
71 return;
72 }
73
b6472664 74 if (myAspectLine == NULL)
2166f0fa 75 {
b6472664 76 myAspectLine = new OpenGl_AspectLine (theAspect);
2166f0fa
SK
77 }
78 else
79 {
b6472664 80 myAspectLine->SetAspect (theAspect);
2166f0fa 81 }
b6472664 82 Update();
2166f0fa
SK
83}
84
4269bd1b 85// =======================================================================
b6472664 86// function : SetPrimitivesAspect
4269bd1b 87// purpose :
88// =======================================================================
b6472664 89void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect)
2166f0fa 90{
b6472664 91 if (myAspectLine == NULL)
b64d84be 92 {
b6472664 93 SetGroupPrimitivesAspect (theAspect);
b64d84be 94 return;
95 }
b6472664 96 else if (IsDeleted())
97 {
98 return;
99 }
100
101 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine (theAspect);
102 AddElement (anAspectLine);
103 Update();
104}
b64d84be 105
b6472664 106// =======================================================================
107// function : SetGroupPrimitivesAspect
108// purpose :
109// =======================================================================
110void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
111{
112 if (IsDeleted())
2166f0fa 113 {
b6472664 114 return;
115 }
116
117 if (myAspectFace == NULL)
118 {
119 myAspectFace = new OpenGl_AspectFace (theAspect);
2166f0fa
SK
120 }
121 else
122 {
b6472664 123 myAspectFace->SetAspect (theAspect);
2166f0fa 124 }
e276548b 125
e276548b 126 if (myIsRaytracable)
127 {
b64d84be 128 OpenGl_Structure* aStruct = GlStruct();
129 if (aStruct != NULL)
e276548b 130 {
d4aaad5b 131 aStruct->UpdateStateIfRaytracable (Standard_False);
e276548b 132 }
133 }
b6472664 134
135 Update();
2166f0fa
SK
136}
137
4269bd1b 138// =======================================================================
b6472664 139// function : SetPrimitivesAspect
4269bd1b 140// purpose :
141// =======================================================================
b6472664 142void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
2166f0fa 143{
b6472664 144 if (myAspectFace == NULL)
145 {
146 SetGroupPrimitivesAspect (theAspect);
147 return;
148 }
149 else if (IsDeleted())
b64d84be 150 {
151 return;
152 }
153
b6472664 154 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace (theAspect);
155 AddElement (anAspectFace);
156 Update();
157}
158
159// =======================================================================
160// function : SetGroupPrimitivesAspect
161// purpose :
162// =======================================================================
163void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker)
164{
165 if (IsDeleted())
2166f0fa 166 {
b6472664 167 return;
168 }
169
170 if (myAspectMarker == NULL)
171 {
172 myAspectMarker = new OpenGl_AspectMarker (theAspMarker);
2166f0fa
SK
173 }
174 else
175 {
b6472664 176 myAspectMarker->SetAspect (theAspMarker);
2166f0fa 177 }
b6472664 178 Update();
2166f0fa
SK
179}
180
4269bd1b 181// =======================================================================
b6472664 182// function : SetPrimitivesAspect
4269bd1b 183// purpose :
184// =======================================================================
b6472664 185void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker)
2166f0fa 186{
b6472664 187 if (myAspectMarker == NULL)
188 {
189 SetGroupPrimitivesAspect (theAspMarker);
190 return;
191 }
192 else if (IsDeleted())
b64d84be 193 {
194 return;
195 }
196
b6472664 197 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker (theAspMarker);
198 AddElement (anAspectMarker);
199 Update();
200}
201
202// =======================================================================
203// function : SetGroupPrimitivesAspect
204// purpose :
205// =======================================================================
206void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText)
207{
208 if (IsDeleted())
2166f0fa 209 {
b6472664 210 return;
211 }
212
213 if (myAspectText == NULL)
214 {
215 myAspectText = new OpenGl_AspectText (theAspText);
2166f0fa
SK
216 }
217 else
218 {
b6472664 219 myAspectText->SetAspect (theAspText);
220 }
221 Update();
222}
223
224// =======================================================================
225// function : SetPrimitivesAspect
226// purpose :
227// =======================================================================
228void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText)
229{
230 if (myAspectText == NULL)
231 {
232 SetGroupPrimitivesAspect (theAspText);
233 return;
234 }
235 else if (IsDeleted())
236 {
237 return;
2166f0fa 238 }
b6472664 239
240 OpenGl_AspectText* anAspectText = new OpenGl_AspectText (theAspText);
241 AddElement (anAspectText);
242 Update();
2166f0fa
SK
243}
244
4269bd1b 245// =======================================================================
b64d84be 246// function : AddPrimitiveArray
247// purpose :
248// =======================================================================
871fa103 249void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
250 const Handle(Graphic3d_IndexBuffer)& theIndices,
251 const Handle(Graphic3d_Buffer)& theAttribs,
252 const Handle(Graphic3d_BoundBuffer)& theBounds,
253 const Standard_Boolean theToEvalMinMax)
b64d84be 254{
255 if (IsDeleted()
871fa103 256 || theAttribs.IsNull())
b64d84be 257 {
258 return;
259 }
260
8d3f219f 261 OpenGl_Structure* aStruct = GlStruct();
262 const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
263
264 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
b64d84be 265 AddElement (anArray);
266
871fa103 267 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
b64d84be 268}
269
270// =======================================================================
271// function : Text
272// purpose :
273// =======================================================================
274void OpenGl_Group::Text (const Standard_CString theTextUtf,
275 const Graphic3d_Vertex& thePoint,
276 const Standard_Real theHeight,
ee2be2a8 277 const Standard_Real theAngle,
b64d84be 278 const Graphic3d_TextPath theTp,
279 const Graphic3d_HorizontalTextAlignment theHta,
280 const Graphic3d_VerticalTextAlignment theVta,
281 const Standard_Boolean theToEvalMinMax)
282{
283 if (IsDeleted())
284 {
285 return;
286 }
287
288 OpenGl_TextParam aParams;
289 OpenGl_Structure* aStruct = GlStruct();
290 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
291 aParams.HAlign = theHta;
292 aParams.VAlign = theVta;
293 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
294 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
295 AddElement (aText);
296 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
297 theTp, theHta, theVta, theToEvalMinMax);
298}
299
300// =======================================================================
ce01ec26 301// function : Text
302// purpose :
303// =======================================================================
304void OpenGl_Group::Text (const Standard_CString theTextUtf,
305 const gp_Ax2& theOrientation,
306 const Standard_Real theHeight,
ee2be2a8 307 const Standard_Real theAngle,
ce01ec26 308 const Graphic3d_TextPath theTp,
309 const Graphic3d_HorizontalTextAlignment theHTA,
310 const Graphic3d_VerticalTextAlignment theVTA,
3f1eb0ab 311 const Standard_Boolean theToEvalMinMax,
312 const Standard_Boolean theHasOwnAnchor)
ce01ec26 313{
314 if (IsDeleted())
315 {
316 return;
317 }
318
319 OpenGl_TextParam aParams;
320 OpenGl_Structure* aStruct = GlStruct();
321
322 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
323 aParams.HAlign = theHTA;
324 aParams.VAlign = theVTA;
325
3f1eb0ab 326 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, theOrientation, aParams, theHasOwnAnchor != Standard_False);
ce01ec26 327
328 AddElement (aText);
329
330 Graphic3d_Group::Text (theTextUtf,
331 theOrientation,
332 theHeight,
333 theAngle,
334 theTp,
335 theHTA,
336 theVTA,
3f1eb0ab 337 theToEvalMinMax,
338 theHasOwnAnchor);
ce01ec26 339
340}
341
342// =======================================================================
b64d84be 343// function : SetFlippingOptions
344// purpose :
345// =======================================================================
346void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
347 const gp_Ax2& theRefPlane)
348{
349 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
350 aFlipper->SetOptions (theIsEnabled);
351 AddElement (aFlipper);
352}
353
354// =======================================================================
355// function : SetStencilTestOptions
356// purpose :
357// =======================================================================
358void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
359{
360 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
361 aStencilTest->SetOptions (theIsEnabled);
362 AddElement (aStencilTest);
363}
364
365// =======================================================================
4269bd1b 366// function : AddElement
367// purpose :
368// =======================================================================
5322131b 369void OpenGl_Group::AddElement (OpenGl_Element* theElem)
2166f0fa 370{
e276548b 371 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
372
e276548b 373 aNode->elem = theElem;
374 aNode->next = NULL;
375 (myLast? myLast->next : myFirst) = aNode;
376 myLast = aNode;
377
e276548b 378 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
379 {
e276548b 380 myIsRaytracable = Standard_True;
2166f0fa 381
b64d84be 382 OpenGl_Structure* aStruct = GlStruct();
383 if (aStruct != NULL)
e276548b 384 {
d4aaad5b 385 aStruct->UpdateStateIfRaytracable (Standard_False);
e276548b 386 }
387 }
2166f0fa
SK
388}
389
4269bd1b 390// =======================================================================
391// function : Render
392// purpose :
393// =======================================================================
bf75be98 394void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
2166f0fa 395{
4269bd1b 396 const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
2166f0fa
SK
397
398 // Setup aspects
25c35042 399 theWorkspace->SetAllowFaceCulling (myIsClosed
400 && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
f9ba5c4d 401 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine();
402 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace();
403 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker();
404 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText();
4269bd1b 405 Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
406 Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
407 Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
408 Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
2166f0fa
SK
409
410 // Render group elements
bf75be98 411 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
2166f0fa 412 {
5322131b 413 aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
2166f0fa
SK
414 }
415
416 // Restore aspects
4269bd1b 417 if (isLineSet)
418 theWorkspace->SetAspectLine (aBackAspectLine);
419 if (isFaceSet)
420 theWorkspace->SetAspectFace (aBackAspectFace);
421 if (isMarkerSet)
422 theWorkspace->SetAspectMarker (aBackAspectMarker);
423 if (isTextSet)
424 theWorkspace->SetAspectText (aBackAspectText);
2166f0fa
SK
425}
426
4269bd1b 427// =======================================================================
b64d84be 428// function : Clear
429// purpose :
430// =======================================================================
431void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
432{
433 if (IsDeleted())
434 {
435 return;
436 }
437
438 OpenGl_Structure* aStruct = GlStruct();
439 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
440
441 Release (aCtx);
442 Graphic3d_Group::Clear (theToUpdateStructureMgr);
d4aaad5b 443
444 myIsRaytracable = Standard_False;
b64d84be 445}
446
447// =======================================================================
4269bd1b 448// function : Release
449// purpose :
450// =======================================================================
5e27df78 451void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
452{
453 // Delete elements
454 while (myFirst != NULL)
455 {
456 OpenGl_ElementNode* aNext = myFirst->next;
10b9c7df 457 OpenGl_Element::Destroy (theGlCtx.operator->(), myFirst->elem);
5e27df78 458 delete myFirst;
459 myFirst = aNext;
460 }
461 myLast = NULL;
462
10b9c7df 463 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
464 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
465 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
466 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
5e27df78 467}