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