1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_Group.hxx>
18 #include <OpenGl_GraphicDriver.hxx>
19 #include <OpenGl_Flipper.hxx>
20 #include <OpenGl_PrimitiveArray.hxx>
21 #include <OpenGl_SceneGeometry.hxx>
22 #include <OpenGl_StencilTest.hxx>
23 #include <OpenGl_Structure.hxx>
24 #include <OpenGl_Text.hxx>
25 #include <OpenGl_Workspace.hxx>
27 #include <Graphic3d_ArrayOfPrimitives.hxx>
28 #include <Graphic3d_GroupDefinitionError.hxx>
30 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group)
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)
45 if (!theWorkspace->ShouldRender (theElement))
50 theElement->Render (theWorkspace);
55 // =======================================================================
56 // function : OpenGl_Group
58 // =======================================================================
59 OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
60 : Graphic3d_Group (theStruct),
67 myIsRaytracable (Standard_False)
69 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
72 throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!");
76 // =======================================================================
77 // function : ~OpenGl_Group
79 // =======================================================================
80 OpenGl_Group::~OpenGl_Group()
82 Release (Handle(OpenGl_Context)());
85 // =======================================================================
86 // function : SetGroupPrimitivesAspect
88 // =======================================================================
89 void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect)
96 if (myAspectLine == NULL)
98 myAspectLine = new OpenGl_AspectLine (theAspect);
102 myAspectLine->SetAspect (theAspect);
107 // =======================================================================
108 // function : SetPrimitivesAspect
110 // =======================================================================
111 void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect)
113 if (myAspectLine == NULL)
115 SetGroupPrimitivesAspect (theAspect);
118 else if (IsDeleted())
123 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine (theAspect);
124 AddElement (anAspectLine);
128 // =======================================================================
129 // function : SetGroupPrimitivesAspect
131 // =======================================================================
132 void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
139 if (myAspectFace == NULL)
141 myAspectFace = new OpenGl_AspectFace (theAspect);
145 myAspectFace->SetAspect (theAspect);
150 OpenGl_Structure* aStruct = GlStruct();
153 aStruct->UpdateStateIfRaytracable (Standard_False);
160 // =======================================================================
161 // function : SetPrimitivesAspect
163 // =======================================================================
164 void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
166 if (myAspectFace == NULL)
168 SetGroupPrimitivesAspect (theAspect);
171 else if (IsDeleted())
176 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace (theAspect);
177 AddElement (anAspectFace);
181 // =======================================================================
182 // function : SetGroupPrimitivesAspect
184 // =======================================================================
185 void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker)
192 if (myAspectMarker == NULL)
194 myAspectMarker = new OpenGl_AspectMarker (theAspMarker);
198 myAspectMarker->SetAspect (theAspMarker);
203 // =======================================================================
204 // function : SetPrimitivesAspect
206 // =======================================================================
207 void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker)
209 if (myAspectMarker == NULL)
211 SetGroupPrimitivesAspect (theAspMarker);
214 else if (IsDeleted())
219 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker (theAspMarker);
220 AddElement (anAspectMarker);
224 // =======================================================================
225 // function : SetGroupPrimitivesAspect
227 // =======================================================================
228 void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText)
235 if (myAspectText == NULL)
237 myAspectText = new OpenGl_AspectText (theAspText);
241 myAspectText->SetAspect (theAspText);
246 // =======================================================================
247 // function : SetPrimitivesAspect
249 // =======================================================================
250 void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText)
252 if (myAspectText == NULL)
254 SetGroupPrimitivesAspect (theAspText);
257 else if (IsDeleted())
262 OpenGl_AspectText* anAspectText = new OpenGl_AspectText (theAspText);
263 AddElement (anAspectText);
267 // =======================================================================
268 // function : SynchronizeAspects
270 // =======================================================================
271 void OpenGl_Group::SynchronizeAspects()
273 if (myAspectFace != NULL)
275 myAspectFace->SynchronizeAspects();
277 if (myAspectLine != NULL)
279 myAspectLine->SynchronizeAspects();
281 if (myAspectMarker != NULL)
283 myAspectMarker->SynchronizeAspects();
285 if (myAspectText != NULL)
287 myAspectText->SynchronizeAspects();
289 for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
291 aNode->elem->SynchronizeAspects();
295 // =======================================================================
296 // function : AddPrimitiveArray
298 // =======================================================================
299 void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
300 const Handle(Graphic3d_IndexBuffer)& theIndices,
301 const Handle(Graphic3d_Buffer)& theAttribs,
302 const Handle(Graphic3d_BoundBuffer)& theBounds,
303 const Standard_Boolean theToEvalMinMax)
306 || theAttribs.IsNull())
311 OpenGl_Structure* aStruct = GlStruct();
312 const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
314 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
315 AddElement (anArray);
317 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
320 // =======================================================================
323 // =======================================================================
324 void OpenGl_Group::Text (const Standard_CString theTextUtf,
325 const Graphic3d_Vertex& thePoint,
326 const Standard_Real theHeight,
327 const Standard_Real theAngle,
328 const Graphic3d_TextPath theTp,
329 const Graphic3d_HorizontalTextAlignment theHta,
330 const Graphic3d_VerticalTextAlignment theVta,
331 const Standard_Boolean theToEvalMinMax)
338 OpenGl_TextParam aParams;
339 OpenGl_Structure* aStruct = GlStruct();
340 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
341 aParams.HAlign = theHta;
342 aParams.VAlign = theVta;
343 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
344 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
346 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
347 theTp, theHta, theVta, theToEvalMinMax);
350 // =======================================================================
353 // =======================================================================
354 void OpenGl_Group::Text (const Standard_CString theTextUtf,
355 const gp_Ax2& theOrientation,
356 const Standard_Real theHeight,
357 const Standard_Real theAngle,
358 const Graphic3d_TextPath theTp,
359 const Graphic3d_HorizontalTextAlignment theHTA,
360 const Graphic3d_VerticalTextAlignment theVTA,
361 const Standard_Boolean theToEvalMinMax,
362 const Standard_Boolean theHasOwnAnchor)
369 OpenGl_TextParam aParams;
370 OpenGl_Structure* aStruct = GlStruct();
372 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
373 aParams.HAlign = theHTA;
374 aParams.VAlign = theVTA;
376 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, theOrientation, aParams, theHasOwnAnchor != Standard_False);
380 Graphic3d_Group::Text (theTextUtf,
392 // =======================================================================
393 // function : SetFlippingOptions
395 // =======================================================================
396 void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
397 const gp_Ax2& theRefPlane)
399 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
400 aFlipper->SetOptions (theIsEnabled);
401 AddElement (aFlipper);
404 // =======================================================================
405 // function : SetStencilTestOptions
407 // =======================================================================
408 void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
410 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
411 aStencilTest->SetOptions (theIsEnabled);
412 AddElement (aStencilTest);
415 // =======================================================================
416 // function : AddElement
418 // =======================================================================
419 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
421 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
423 aNode->elem = theElem;
425 (myLast? myLast->next : myFirst) = aNode;
428 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
430 myIsRaytracable = Standard_True;
432 OpenGl_Structure* aStruct = GlStruct();
435 aStruct->UpdateStateIfRaytracable (Standard_False);
440 // =======================================================================
443 // =======================================================================
444 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
447 theWorkspace->SetAllowFaceCulling (myIsClosed
448 && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
449 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine();
450 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace();
451 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker();
452 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText();
453 const bool isLineSet = myAspectLine && renderFiltered (theWorkspace, myAspectLine);
454 const bool isFaceSet = myAspectFace && renderFiltered (theWorkspace, myAspectFace);
455 const bool isMarkerSet = myAspectMarker && renderFiltered (theWorkspace, myAspectMarker);
456 const bool isTextSet = myAspectText && renderFiltered (theWorkspace, myAspectText);
458 // Render group elements
459 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
461 renderFiltered (theWorkspace, aNodeIter->elem);
466 theWorkspace->SetAspectLine (aBackAspectLine);
468 theWorkspace->SetAspectFace (aBackAspectFace);
470 theWorkspace->SetAspectMarker (aBackAspectMarker);
472 theWorkspace->SetAspectText (aBackAspectText);
475 // =======================================================================
478 // =======================================================================
479 void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
486 OpenGl_Structure* aStruct = GlStruct();
487 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
490 Graphic3d_Group::Clear (theToUpdateStructureMgr);
492 myIsRaytracable = Standard_False;
495 // =======================================================================
496 // function : Release
498 // =======================================================================
499 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
502 while (myFirst != NULL)
504 OpenGl_ElementNode* aNext = myFirst->next;
505 OpenGl_Element::Destroy (theGlCtx.operator->(), myFirst->elem);
511 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
512 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
513 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
514 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);