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)
32 // =======================================================================
33 // function : OpenGl_Group
35 // =======================================================================
36 OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
37 : Graphic3d_Group (theStruct),
41 myIsRaytracable (Standard_False)
43 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
46 throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!");
50 // =======================================================================
51 // function : ~OpenGl_Group
53 // =======================================================================
54 OpenGl_Group::~OpenGl_Group()
56 Release (Handle(OpenGl_Context)());
59 // =======================================================================
60 // function : SetGroupPrimitivesAspect
62 // =======================================================================
63 void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
70 if (myAspects == NULL)
72 myAspects = new OpenGl_Aspects (theAspect);
76 myAspects->SetAspect (theAspect);
79 if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
81 aStruct->UpdateStateIfRaytracable (Standard_False);
87 // =======================================================================
88 // function : SetPrimitivesAspect
90 // =======================================================================
91 void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect)
93 if (myAspects == NULL)
95 SetGroupPrimitivesAspect (theAspect);
103 OpenGl_Aspects* anAspects = new OpenGl_Aspects (theAspect);
104 AddElement (anAspects);
108 // =======================================================================
109 // function : SynchronizeAspects
111 // =======================================================================
112 void OpenGl_Group::SynchronizeAspects()
114 if (myAspects != NULL)
116 myAspects->SynchronizeAspects();
117 if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
119 aStruct->UpdateStateIfRaytracable (Standard_False);
122 for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
124 aNode->elem->SynchronizeAspects();
128 // =======================================================================
129 // function : ReplaceAspects
131 // =======================================================================
132 void OpenGl_Group::ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap)
134 if (theMap.IsEmpty())
139 Handle(Graphic3d_Aspects) anAspect;
140 if (myAspects != NULL
141 && theMap.Find (myAspects->Aspect(), anAspect))
143 myAspects->SetAspect (anAspect);
144 if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL)
146 aStruct->UpdateStateIfRaytracable (Standard_False);
149 for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
151 OpenGl_Aspects* aGlAspect = dynamic_cast<OpenGl_Aspects*> (aNode->elem);
152 if (aGlAspect != NULL
153 && theMap.Find (aGlAspect->Aspect(), anAspect))
155 aGlAspect->SetAspect (anAspect);
160 // =======================================================================
161 // function : AddPrimitiveArray
163 // =======================================================================
164 void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
165 const Handle(Graphic3d_IndexBuffer)& theIndices,
166 const Handle(Graphic3d_Buffer)& theAttribs,
167 const Handle(Graphic3d_BoundBuffer)& theBounds,
168 const Standard_Boolean theToEvalMinMax)
171 || theAttribs.IsNull())
176 OpenGl_Structure* aStruct = GlStruct();
177 const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver();
179 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds);
180 AddElement (anArray);
182 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
185 // =======================================================================
186 // function : AddText
188 // =======================================================================
189 void OpenGl_Group::AddText (const Handle(Graphic3d_Text)& theTextParams,
190 const Standard_Boolean theToEvalMinMax)
197 if (theTextParams->Height() < 2.0)
199 // TODO - this should be handled in different way (throw exception / take default text height without modifying Graphic3d_Text / log warning, etc.)
200 OpenGl_Structure* aStruct = GlStruct();
201 theTextParams->SetHeight (aStruct->GlDriver()->DefaultTextHeight());
203 OpenGl_Text* aText = new OpenGl_Text (theTextParams);
206 Graphic3d_Group::AddText (theTextParams, theToEvalMinMax);
209 // =======================================================================
210 // function : SetFlippingOptions
212 // =======================================================================
213 void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
214 const gp_Ax2& theRefPlane)
216 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
217 aFlipper->SetOptions (theIsEnabled);
218 AddElement (aFlipper);
221 // =======================================================================
222 // function : SetStencilTestOptions
224 // =======================================================================
225 void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
227 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
228 aStencilTest->SetOptions (theIsEnabled);
229 AddElement (aStencilTest);
232 // =======================================================================
233 // function : AddElement
235 // =======================================================================
236 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
238 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
240 aNode->elem = theElem;
242 (myLast? myLast->next : myFirst) = aNode;
245 if (OpenGl_Raytrace::IsRaytracedElement (aNode) && !HasPersistence())
247 myIsRaytracable = Standard_True;
249 OpenGl_Structure* aStruct = GlStruct();
252 aStruct->UpdateStateIfRaytracable (Standard_False);
257 // =======================================================================
258 // function : renderFiltered
260 // =======================================================================
261 bool OpenGl_Group::renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace,
262 OpenGl_Element* theElement) const
264 if (!theWorkspace->ShouldRender (theElement, this))
269 theElement->Render (theWorkspace);
273 // =======================================================================
276 // =======================================================================
277 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
280 theWorkspace->SetAllowFaceCulling (myIsClosed
281 && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
282 const OpenGl_Aspects* aBackAspects = theWorkspace->Aspects();
283 const bool isAspectSet = myAspects != NULL && renderFiltered (theWorkspace, myAspects);
285 // Render group elements
286 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
288 renderFiltered (theWorkspace, aNodeIter->elem);
293 theWorkspace->SetAspects (aBackAspects);
296 // =======================================================================
299 // =======================================================================
300 void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
307 OpenGl_Structure* aStruct = GlStruct();
308 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
311 Graphic3d_Group::Clear (theToUpdateStructureMgr);
313 myIsRaytracable = Standard_False;
316 // =======================================================================
317 // function : Release
319 // =======================================================================
320 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
323 while (myFirst != NULL)
325 OpenGl_ElementNode* aNext = myFirst->next;
326 OpenGl_Element::Destroy (theGlCtx.get(), myFirst->elem);
332 OpenGl_Element::Destroy (theGlCtx.get(), myAspects);
335 // =======================================================================
336 // function : DumpJson
338 // =======================================================================
339 void OpenGl_Group::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
341 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
343 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Graphic3d_Group)
345 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myAspects)
346 for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next)
348 OpenGl_Element* anElement = aNode->elem;
349 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anElement)
351 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsRaytracable)