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_StencilTest.hxx>
22 #include <OpenGl_Structure.hxx>
23 #include <OpenGl_Text.hxx>
24 #include <OpenGl_Workspace.hxx>
26 #include <Graphic3d_ArrayOfPrimitives.hxx>
27 #include <Graphic3d_CUserDraw.hxx>
28 #include <Graphic3d_GroupDefinitionError.hxx>
30 IMPLEMENT_STANDARD_HANDLE (OpenGl_Group, Graphic3d_Group)
31 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group, Graphic3d_Group)
33 // =======================================================================
34 // function : OpenGl_Group
36 // =======================================================================
37 OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
38 : Graphic3d_Group (theStruct),
45 myIsRaytracable (Standard_False),
46 myModificationState (0)
48 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
51 Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!");
55 // =======================================================================
56 // function : ~OpenGl_Group
58 // =======================================================================
59 OpenGl_Group::~OpenGl_Group()
61 Release (Handle(OpenGl_Context)());
64 // =======================================================================
65 // function : UpdateAspectLine
67 // =======================================================================
68 void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal)
70 if (!ContextLine.IsDef)
75 if (theIsGlobal || myFirst == NULL)
77 if (myAspectLine == NULL)
79 myAspectLine = new OpenGl_AspectLine();
81 myAspectLine->SetAspect (ContextLine);
85 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
86 anAspectLine->SetAspect (ContextLine);
87 AddElement (anAspectLine);
91 // =======================================================================
92 // function : UpdateAspectFace
94 // =======================================================================
95 void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal)
97 if (!ContextFillArea.IsDef)
102 if (theIsGlobal || myFirst == NULL)
104 if (myAspectFace == NULL)
106 myAspectFace = new OpenGl_AspectFace();
108 myAspectFace->SetAspect (ContextFillArea);
112 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
113 anAspectFace->SetAspect (ContextFillArea);
114 AddElement (anAspectFace);
119 ++myModificationState;
120 OpenGl_Structure* aStruct = GlStruct();
123 aStruct->UpdateStateWithAncestorStructures();
128 // =======================================================================
129 // function : UpdateAspectMarker
131 // =======================================================================
132 void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal)
134 if (!ContextMarker.IsDef)
139 if (theIsGlobal || myFirst == NULL)
141 if (myAspectMarker == NULL)
143 myAspectMarker = new OpenGl_AspectMarker();
145 myAspectMarker->SetAspect (ContextMarker);
149 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
150 anAspectMarker->SetAspect (ContextMarker);
151 AddElement (anAspectMarker);
155 // =======================================================================
156 // function : UpdateAspectText
158 // =======================================================================
159 void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
161 if (!ContextText.IsDef)
166 if (theIsGlobal || myFirst == NULL)
168 if (myAspectText == NULL)
170 myAspectText = new OpenGl_AspectText();
172 myAspectText->SetAspect (ContextText);
176 OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
177 anAspectText->SetAspect (ContextText);
178 AddElement (anAspectText);
182 // =======================================================================
183 // function : AddPrimitiveArray
185 // =======================================================================
186 void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
187 const Handle(Graphic3d_IndexBuffer)& theIndices,
188 const Handle(Graphic3d_Buffer)& theAttribs,
189 const Handle(Graphic3d_BoundBuffer)& theBounds,
190 const Standard_Boolean theToEvalMinMax)
193 || theAttribs.IsNull())
198 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (theType, theIndices, theAttribs, theBounds);
199 AddElement (anArray);
201 Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
204 // =======================================================================
207 // =======================================================================
208 void OpenGl_Group::Text (const Standard_CString theTextUtf,
209 const Graphic3d_Vertex& thePoint,
210 const Standard_Real theHeight,
211 const Quantity_PlaneAngle theAngle,
212 const Graphic3d_TextPath theTp,
213 const Graphic3d_HorizontalTextAlignment theHta,
214 const Graphic3d_VerticalTextAlignment theVta,
215 const Standard_Boolean theToEvalMinMax)
222 OpenGl_TextParam aParams;
223 OpenGl_Structure* aStruct = GlStruct();
224 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
225 aParams.HAlign = theHta;
226 aParams.VAlign = theVta;
227 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
228 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
230 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
231 theTp, theHta, theVta, theToEvalMinMax);
234 // =======================================================================
235 // function : UserDraw
237 // =======================================================================
238 void OpenGl_Group::UserDraw (const Standard_Address theObject,
239 const Standard_Boolean theToEvalMinMax,
240 const Standard_Boolean theContainsFacet)
247 OpenGl_Structure* aStruct = GlStruct();
248 if (aStruct->GlDriver()->UserDrawCallback() == NULL)
253 Graphic3d_CUserDraw aUserDraw;
254 aUserDraw.Data = theObject;
255 aUserDraw.Bounds = theToEvalMinMax ? &myBounds : NULL;
256 OpenGl_Element* aUserDrawElem = aStruct->GlDriver()->UserDrawCallback()(&aUserDraw);
257 if (aUserDrawElem != NULL)
259 AddElement (aUserDrawElem);
261 Graphic3d_Group::UserDraw (theObject, theToEvalMinMax, theContainsFacet);
264 // =======================================================================
265 // function : SetFlippingOptions
267 // =======================================================================
268 void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
269 const gp_Ax2& theRefPlane)
271 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
272 aFlipper->SetOptions (theIsEnabled);
273 AddElement (aFlipper);
276 // =======================================================================
277 // function : SetStencilTestOptions
279 // =======================================================================
280 void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
282 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
283 aStencilTest->SetOptions (theIsEnabled);
284 AddElement (aStencilTest);
287 // =======================================================================
288 // function : AddElement
290 // =======================================================================
291 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
293 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
295 aNode->elem = theElem;
297 (myLast? myLast->next : myFirst) = aNode;
300 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
302 myModificationState++;
303 myIsRaytracable = Standard_True;
305 OpenGl_Structure* aStruct = GlStruct();
308 aStruct->UpdateStateWithAncestorStructures();
309 aStruct->SetRaytracableWithAncestorStructures();
314 // =======================================================================
317 // =======================================================================
318 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
320 // Is rendering in ADD or IMMEDIATE mode?
321 const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
324 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
325 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
326 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
327 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
328 Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
329 Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
330 Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
331 Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
333 // Render group elements
334 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
336 aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
341 theWorkspace->SetAspectLine (aBackAspectLine);
343 theWorkspace->SetAspectFace (aBackAspectFace);
345 theWorkspace->SetAspectMarker (aBackAspectMarker);
347 theWorkspace->SetAspectText (aBackAspectText);
350 // =======================================================================
353 // =======================================================================
354 void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
361 OpenGl_Structure* aStruct = GlStruct();
362 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
365 Graphic3d_Group::Clear (theToUpdateStructureMgr);
368 // =======================================================================
369 // function : Release
371 // =======================================================================
372 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
375 while (myFirst != NULL)
377 OpenGl_ElementNode* aNext = myFirst->next;
378 OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
384 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
385 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
386 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
387 OpenGl_Element::Destroy (theGlCtx, myAspectText);