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),
64 myIsRaytracable (Standard_False)
66 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
69 throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!");
73 // =======================================================================
74 // function : ~OpenGl_Group
76 // =======================================================================
77 OpenGl_Group::~OpenGl_Group()
79 Release (Handle(OpenGl_Context)());
82 // =======================================================================
83 // function : SetGroupPrimitivesAspect
85 // =======================================================================
86 void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
93 if (myAspects == NULL)
95 myAspects = new OpenGl_Aspects (theAspect);
99 myAspects->SetAspect (theAspect);
102 if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
104 aStruct->UpdateStateIfRaytracable (Standard_False);
110 // =======================================================================
111 // function : SetPrimitivesAspect
113 // =======================================================================
114 void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
116 if (myAspects == NULL)
118 SetGroupPrimitivesAspect (theAspect);
121 else if (IsDeleted())
126 OpenGl_Aspects* anAspects = new OpenGl_Aspects (theAspect);
127 AddElement (anAspects);
131 // =======================================================================
132 // function : SynchronizeAspects
134 // =======================================================================
135 void OpenGl_Group::SynchronizeAspects()
137 if (myAspects != NULL)
139 myAspects->SynchronizeAspects();
140 if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
142 aStruct->UpdateStateIfRaytracable (Standard_False);
145 for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
147 aNode->elem->SynchronizeAspects();
151 // =======================================================================
152 // function : ReplaceAspects
154 // =======================================================================
155 void OpenGl_Group::ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap)
157 if (theMap.IsEmpty())
162 Handle(Graphic3d_Aspects) anAspect;
163 if (myAspects != NULL
164 && theMap.Find (myAspects->Aspect(), anAspect))
166 myAspects->SetAspect (anAspect);
167 if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
169 aStruct->UpdateStateIfRaytracable (Standard_False);
172 for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
174 OpenGl_Aspects* aGlAspect = dynamic_cast<OpenGl_Aspects*> (aNode->elem);
175 if (aGlAspect != NULL
176 && theMap.Find (aGlAspect->Aspect(), anAspect))
178 aGlAspect->SetAspect (anAspect);
183 // =======================================================================
184 // function : AddPrimitiveArray
186 // =======================================================================
187 void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
188 const Handle(Graphic3d_IndexBuffer)& theIndices,
189 const Handle(Graphic3d_Buffer)& theAttribs,
190 const Handle(Graphic3d_BoundBuffer)& theBounds,
191 const Standard_Boolean theToEvalMinMax)
194 || theAttribs.IsNull())
199 OpenGl_Structure* aStruct = GlStruct();
200 const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
202 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
203 AddElement (anArray);
205 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
208 // =======================================================================
211 // =======================================================================
212 void OpenGl_Group::Text (const Standard_CString theTextUtf,
213 const Graphic3d_Vertex& thePoint,
214 const Standard_Real theHeight,
215 const Standard_Real theAngle,
216 const Graphic3d_TextPath theTp,
217 const Graphic3d_HorizontalTextAlignment theHta,
218 const Graphic3d_VerticalTextAlignment theVta,
219 const Standard_Boolean theToEvalMinMax)
226 OpenGl_TextParam aParams;
227 OpenGl_Structure* aStruct = GlStruct();
228 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
229 aParams.HAlign = theHta;
230 aParams.VAlign = theVta;
231 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
232 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
234 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
235 theTp, theHta, theVta, theToEvalMinMax);
238 // =======================================================================
241 // =======================================================================
242 void OpenGl_Group::Text (const Standard_CString theTextUtf,
243 const gp_Ax2& theOrientation,
244 const Standard_Real theHeight,
245 const Standard_Real theAngle,
246 const Graphic3d_TextPath theTp,
247 const Graphic3d_HorizontalTextAlignment theHTA,
248 const Graphic3d_VerticalTextAlignment theVTA,
249 const Standard_Boolean theToEvalMinMax,
250 const Standard_Boolean theHasOwnAnchor)
257 OpenGl_TextParam aParams;
258 OpenGl_Structure* aStruct = GlStruct();
260 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
261 aParams.HAlign = theHTA;
262 aParams.VAlign = theVTA;
264 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, theOrientation, aParams, theHasOwnAnchor != Standard_False);
268 Graphic3d_Group::Text (theTextUtf,
280 // =======================================================================
281 // function : SetFlippingOptions
283 // =======================================================================
284 void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
285 const gp_Ax2& theRefPlane)
287 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
288 aFlipper->SetOptions (theIsEnabled);
289 AddElement (aFlipper);
292 // =======================================================================
293 // function : SetStencilTestOptions
295 // =======================================================================
296 void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
298 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
299 aStencilTest->SetOptions (theIsEnabled);
300 AddElement (aStencilTest);
303 // =======================================================================
304 // function : AddElement
306 // =======================================================================
307 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
309 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
311 aNode->elem = theElem;
313 (myLast? myLast->next : myFirst) = aNode;
316 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
318 myIsRaytracable = Standard_True;
320 OpenGl_Structure* aStruct = GlStruct();
323 aStruct->UpdateStateIfRaytracable (Standard_False);
328 // =======================================================================
331 // =======================================================================
332 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
335 theWorkspace->SetAllowFaceCulling (myIsClosed
336 && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
337 const OpenGl_Aspects* aBackAspects = theWorkspace->Aspects();
338 const bool isAspectSet = myAspects != NULL && renderFiltered (theWorkspace, myAspects);
340 // Render group elements
341 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
343 renderFiltered (theWorkspace, aNodeIter->elem);
348 theWorkspace->SetAspects (aBackAspects);
351 // =======================================================================
354 // =======================================================================
355 void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
362 OpenGl_Structure* aStruct = GlStruct();
363 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
366 Graphic3d_Group::Clear (theToUpdateStructureMgr);
368 myIsRaytracable = Standard_False;
371 // =======================================================================
372 // function : Release
374 // =======================================================================
375 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
378 while (myFirst != NULL)
380 OpenGl_ElementNode* aNext = myFirst->next;
381 OpenGl_Element::Destroy (theGlCtx.operator->(), myFirst->elem);
387 OpenGl_Element::Destroy (theGlCtx.operator->(), myAspects);