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.
20 #include <OpenGl_Group.hxx>
22 #include <OpenGl_GraphicDriver.hxx>
23 #include <OpenGl_Flipper.hxx>
24 #include <OpenGl_PrimitiveArray.hxx>
25 #include <OpenGl_StencilTest.hxx>
26 #include <OpenGl_Structure.hxx>
27 #include <OpenGl_Text.hxx>
28 #include <OpenGl_Workspace.hxx>
30 #include <Graphic3d_ArrayOfPrimitives.hxx>
31 #include <Graphic3d_CUserDraw.hxx>
32 #include <Graphic3d_GroupDefinitionError.hxx>
34 IMPLEMENT_STANDARD_HANDLE (OpenGl_Group, Graphic3d_Group)
35 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group, Graphic3d_Group)
37 // =======================================================================
38 // function : OpenGl_Group
40 // =======================================================================
41 OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct)
42 : Graphic3d_Group (theStruct),
49 myIsRaytracable (Standard_False),
50 myModificationState (0)
52 Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure());
55 Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!");
59 // =======================================================================
60 // function : ~OpenGl_Group
62 // =======================================================================
63 OpenGl_Group::~OpenGl_Group()
65 Release (Handle(OpenGl_Context)());
68 // =======================================================================
69 // function : UpdateAspectLine
71 // =======================================================================
72 void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal)
74 if (!ContextLine.IsDef)
79 if (theIsGlobal || myFirst == NULL)
81 if (myAspectLine == NULL)
83 myAspectLine = new OpenGl_AspectLine();
85 myAspectLine->SetAspect (ContextLine);
89 OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
90 anAspectLine->SetAspect (ContextLine);
91 AddElement (anAspectLine);
95 // =======================================================================
96 // function : UpdateAspectFace
98 // =======================================================================
99 void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal)
101 if (!ContextFillArea.IsDef)
106 if (theIsGlobal || myFirst == NULL)
108 if (myAspectFace == NULL)
110 myAspectFace = new OpenGl_AspectFace();
112 myAspectFace->SetAspect (ContextFillArea);
116 OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
117 anAspectFace->SetAspect (ContextFillArea);
118 AddElement (anAspectFace);
124 ++myModificationState;
125 OpenGl_Structure* aStruct = GlStruct();
128 aStruct->UpdateStateWithAncestorStructures();
134 // =======================================================================
135 // function : UpdateAspectMarker
137 // =======================================================================
138 void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal)
140 if (!ContextMarker.IsDef)
145 if (theIsGlobal || myFirst == NULL)
147 if (myAspectMarker == NULL)
149 myAspectMarker = new OpenGl_AspectMarker();
151 myAspectMarker->SetAspect (ContextMarker);
155 OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
156 anAspectMarker->SetAspect (ContextMarker);
157 AddElement (anAspectMarker);
161 // =======================================================================
162 // function : UpdateAspectText
164 // =======================================================================
165 void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
167 if (!ContextText.IsDef)
172 if (theIsGlobal || myFirst == NULL)
174 if (myAspectText == NULL)
176 myAspectText = new OpenGl_AspectText();
178 myAspectText->SetAspect (ContextText);
182 OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
183 anAspectText->SetAspect (ContextText);
184 AddElement (anAspectText);
188 // =======================================================================
189 // function : AddPrimitiveArray
191 // =======================================================================
192 void OpenGl_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
193 const Standard_Boolean theToEvalMinMax)
196 || !thePrim->IsValid())
201 OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray ((CALL_DEF_PARRAY *)thePrim->Array());
202 AddElement (anArray);
204 Graphic3d_Group::AddPrimitiveArray (thePrim, theToEvalMinMax);
207 // =======================================================================
210 // =======================================================================
211 void OpenGl_Group::Text (const Standard_CString theTextUtf,
212 const Graphic3d_Vertex& thePoint,
213 const Standard_Real theHeight,
214 const Quantity_PlaneAngle theAngle,
215 const Graphic3d_TextPath theTp,
216 const Graphic3d_HorizontalTextAlignment theHta,
217 const Graphic3d_VerticalTextAlignment theVta,
218 const Standard_Boolean theToEvalMinMax)
225 OpenGl_TextParam aParams;
226 OpenGl_Structure* aStruct = GlStruct();
227 aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight);
228 aParams.HAlign = theHta;
229 aParams.VAlign = theVta;
230 const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
231 OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams);
233 Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle,
234 theTp, theHta, theVta, theToEvalMinMax);
237 // =======================================================================
238 // function : UserDraw
240 // =======================================================================
241 void OpenGl_Group::UserDraw (const Standard_Address theObject,
242 const Standard_Boolean theToEvalMinMax,
243 const Standard_Boolean theContainsFacet)
250 OpenGl_Structure* aStruct = GlStruct();
251 if (aStruct->GlDriver()->UserDrawCallback() == NULL)
256 Graphic3d_CUserDraw aUserDraw;
257 aUserDraw.Data = theObject;
258 aUserDraw.Bounds = theToEvalMinMax ? &myBounds : NULL;
259 OpenGl_Element* aUserDrawElem = aStruct->GlDriver()->UserDrawCallback()(&aUserDraw);
260 if (aUserDrawElem != NULL)
262 AddElement (aUserDrawElem);
264 Graphic3d_Group::UserDraw (theObject, theToEvalMinMax, theContainsFacet);
267 // =======================================================================
268 // function : SetFlippingOptions
270 // =======================================================================
271 void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
272 const gp_Ax2& theRefPlane)
274 OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
275 aFlipper->SetOptions (theIsEnabled);
276 AddElement (aFlipper);
279 // =======================================================================
280 // function : SetStencilTestOptions
282 // =======================================================================
283 void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled)
285 OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest();
286 aStencilTest->SetOptions (theIsEnabled);
287 AddElement (aStencilTest);
290 // =======================================================================
291 // function : AddElement
293 // =======================================================================
294 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
296 OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
298 aNode->elem = theElem;
300 (myLast? myLast->next : myFirst) = aNode;
304 if (OpenGl_Raytrace::IsRaytracedElement (aNode))
306 myModificationState++;
307 myIsRaytracable = Standard_True;
309 OpenGl_Structure* aStruct = GlStruct();
312 aStruct->UpdateStateWithAncestorStructures();
313 aStruct->SetRaytracableWithAncestorStructures();
319 // =======================================================================
322 // =======================================================================
323 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
325 // Is rendering in ADD or IMMEDIATE mode?
326 const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
329 const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False);
330 const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False);
331 const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
332 const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False);
333 Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter);
334 Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter);
335 Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
336 Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter);
338 // Render group elements
339 for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
341 aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
346 theWorkspace->SetAspectLine (aBackAspectLine);
348 theWorkspace->SetAspectFace (aBackAspectFace);
350 theWorkspace->SetAspectMarker (aBackAspectMarker);
352 theWorkspace->SetAspectText (aBackAspectText);
355 // =======================================================================
358 // =======================================================================
359 void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr)
366 OpenGl_Structure* aStruct = GlStruct();
367 const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext();
370 Graphic3d_Group::Clear (theToUpdateStructureMgr);
373 // =======================================================================
374 // function : Release
376 // =======================================================================
377 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
380 while (myFirst != NULL)
382 OpenGl_ElementNode* aNext = myFirst->next;
383 OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
389 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
390 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
391 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
392 OpenGl_Element::Destroy (theGlCtx, myAspectText);