Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-08-01 |
2 | // Created by: Sergey ZERCHANINOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
2166f0fa | 15 | |
e276548b | 16 | #include <OpenGl_Group.hxx> |
b64d84be | 17 | |
18 | #include <OpenGl_GraphicDriver.hxx> | |
19 | #include <OpenGl_Flipper.hxx> | |
2166f0fa | 20 | #include <OpenGl_PrimitiveArray.hxx> |
c357e426 | 21 | #include <OpenGl_SceneGeometry.hxx> |
b64d84be | 22 | #include <OpenGl_StencilTest.hxx> |
e276548b | 23 | #include <OpenGl_Structure.hxx> |
b64d84be | 24 | #include <OpenGl_Text.hxx> |
bf75be98 | 25 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 26 | |
b64d84be | 27 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
b64d84be | 28 | #include <Graphic3d_GroupDefinitionError.hxx> |
29 | ||
92efcf78 | 30 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group) |
31 | ||
4269bd1b | 32 | // ======================================================================= |
33 | // function : OpenGl_Group | |
34 | // purpose : | |
35 | // ======================================================================= | |
b64d84be | 36 | OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct) |
37 | : Graphic3d_Group (theStruct), | |
bf5f0ca2 | 38 | myAspects(NULL), |
e276548b | 39 | myFirst(NULL), |
b64d84be | 40 | myLast(NULL), |
d4aaad5b | 41 | myIsRaytracable (Standard_False) |
2166f0fa | 42 | { |
b64d84be | 43 | Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure()); |
c04c30b3 | 44 | if (aStruct.IsNull()) |
b64d84be | 45 | { |
9775fa61 | 46 | throw Graphic3d_GroupDefinitionError("OpenGl_Group should be created by OpenGl_Structure!"); |
b64d84be | 47 | } |
2166f0fa SK |
48 | } |
49 | ||
4269bd1b | 50 | // ======================================================================= |
51 | // function : ~OpenGl_Group | |
52 | // purpose : | |
53 | // ======================================================================= | |
2166f0fa SK |
54 | OpenGl_Group::~OpenGl_Group() |
55 | { | |
5e27df78 | 56 | Release (Handle(OpenGl_Context)()); |
2166f0fa SK |
57 | } |
58 | ||
4269bd1b | 59 | // ======================================================================= |
b6472664 | 60 | // function : SetGroupPrimitivesAspect |
4269bd1b | 61 | // purpose : |
62 | // ======================================================================= | |
bf5f0ca2 | 63 | void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) |
2166f0fa | 64 | { |
b6472664 | 65 | if (IsDeleted()) |
b64d84be | 66 | { |
67 | return; | |
68 | } | |
69 | ||
bf5f0ca2 | 70 | if (myAspects == NULL) |
2166f0fa | 71 | { |
bf5f0ca2 | 72 | myAspects = new OpenGl_Aspects (theAspect); |
2166f0fa SK |
73 | } |
74 | else | |
75 | { | |
bf5f0ca2 | 76 | myAspects->SetAspect (theAspect); |
b6472664 | 77 | } |
78 | ||
bf5f0ca2 | 79 | if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL) |
b6472664 | 80 | { |
bf5f0ca2 | 81 | aStruct->UpdateStateIfRaytracable (Standard_False); |
e276548b | 82 | } |
b6472664 | 83 | |
84 | Update(); | |
2166f0fa SK |
85 | } |
86 | ||
4269bd1b | 87 | // ======================================================================= |
b6472664 | 88 | // function : SetPrimitivesAspect |
4269bd1b | 89 | // purpose : |
90 | // ======================================================================= | |
bf5f0ca2 | 91 | void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) |
2166f0fa | 92 | { |
bf5f0ca2 | 93 | if (myAspects == NULL) |
b6472664 | 94 | { |
95 | SetGroupPrimitivesAspect (theAspect); | |
96 | return; | |
97 | } | |
98 | else if (IsDeleted()) | |
b64d84be | 99 | { |
100 | return; | |
101 | } | |
102 | ||
bf5f0ca2 | 103 | OpenGl_Aspects* anAspects = new OpenGl_Aspects (theAspect); |
104 | AddElement (anAspects); | |
b6472664 | 105 | Update(); |
2166f0fa SK |
106 | } |
107 | ||
4269bd1b | 108 | // ======================================================================= |
bf5f0ca2 | 109 | // function : SynchronizeAspects |
b6472664 | 110 | // purpose : |
111 | // ======================================================================= | |
bf5f0ca2 | 112 | void OpenGl_Group::SynchronizeAspects() |
b6472664 | 113 | { |
bf5f0ca2 | 114 | if (myAspects != NULL) |
b6472664 | 115 | { |
bf5f0ca2 | 116 | myAspects->SynchronizeAspects(); |
117 | if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL) | |
118 | { | |
119 | aStruct->UpdateStateIfRaytracable (Standard_False); | |
120 | } | |
2166f0fa | 121 | } |
bf5f0ca2 | 122 | for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next) |
2166f0fa | 123 | { |
bf5f0ca2 | 124 | aNode->elem->SynchronizeAspects(); |
b6472664 | 125 | } |
b6472664 | 126 | } |
127 | ||
128 | // ======================================================================= | |
bf5f0ca2 | 129 | // function : ReplaceAspects |
b6472664 | 130 | // purpose : |
131 | // ======================================================================= | |
bf5f0ca2 | 132 | void OpenGl_Group::ReplaceAspects (const Graphic3d_MapOfAspectsToAspects& theMap) |
b6472664 | 133 | { |
bf5f0ca2 | 134 | if (theMap.IsEmpty()) |
b6472664 | 135 | { |
136 | return; | |
2166f0fa | 137 | } |
b6472664 | 138 | |
bf5f0ca2 | 139 | Handle(Graphic3d_Aspects) anAspect; |
140 | if (myAspects != NULL | |
141 | && theMap.Find (myAspects->Aspect(), anAspect)) | |
eaac0866 | 142 | { |
bf5f0ca2 | 143 | myAspects->SetAspect (anAspect); |
144 | if (OpenGl_Structure* aStruct = myIsRaytracable ? GlStruct() : NULL) | |
145 | { | |
146 | aStruct->UpdateStateIfRaytracable (Standard_False); | |
147 | } | |
eaac0866 | 148 | } |
149 | for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next) | |
150 | { | |
bf5f0ca2 | 151 | OpenGl_Aspects* aGlAspect = dynamic_cast<OpenGl_Aspects*> (aNode->elem); |
152 | if (aGlAspect != NULL | |
153 | && theMap.Find (aGlAspect->Aspect(), anAspect)) | |
154 | { | |
155 | aGlAspect->SetAspect (anAspect); | |
156 | } | |
eaac0866 | 157 | } |
158 | } | |
159 | ||
b64d84be | 160 | // ======================================================================= |
161 | // function : AddPrimitiveArray | |
162 | // purpose : | |
163 | // ======================================================================= | |
871fa103 | 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) | |
b64d84be | 169 | { |
170 | if (IsDeleted() | |
871fa103 | 171 | || theAttribs.IsNull()) |
b64d84be | 172 | { |
173 | return; | |
174 | } | |
175 | ||
8d3f219f | 176 | OpenGl_Structure* aStruct = GlStruct(); |
177 | const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver(); | |
178 | ||
179 | OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds); | |
b64d84be | 180 | AddElement (anArray); |
181 | ||
871fa103 | 182 | Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax); |
b64d84be | 183 | } |
184 | ||
185 | // ======================================================================= | |
8ed07085 | 186 | // function : AddText |
b64d84be | 187 | // purpose : |
188 | // ======================================================================= | |
8ed07085 | 189 | void OpenGl_Group::AddText (const Handle(Graphic3d_Text)& theTextParams, |
190 | const Standard_Boolean theToEvalMinMax) | |
b64d84be | 191 | { |
192 | if (IsDeleted()) | |
193 | { | |
194 | return; | |
195 | } | |
196 | ||
8ed07085 | 197 | if (theTextParams->Height() < 2.0) |
ce01ec26 | 198 | { |
8ed07085 | 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()); | |
ce01ec26 | 202 | } |
8ed07085 | 203 | OpenGl_Text* aText = new OpenGl_Text (theTextParams); |
ce01ec26 | 204 | |
205 | AddElement (aText); | |
8ed07085 | 206 | Graphic3d_Group::AddText (theTextParams, theToEvalMinMax); |
ce01ec26 | 207 | } |
208 | ||
b64d84be | 209 | // ======================================================================= |
210 | // function : SetFlippingOptions | |
211 | // purpose : | |
212 | // ======================================================================= | |
213 | void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled, | |
214 | const gp_Ax2& theRefPlane) | |
215 | { | |
216 | OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane); | |
217 | aFlipper->SetOptions (theIsEnabled); | |
218 | AddElement (aFlipper); | |
219 | } | |
220 | ||
221 | // ======================================================================= | |
222 | // function : SetStencilTestOptions | |
223 | // purpose : | |
224 | // ======================================================================= | |
225 | void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled) | |
226 | { | |
227 | OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest(); | |
228 | aStencilTest->SetOptions (theIsEnabled); | |
229 | AddElement (aStencilTest); | |
230 | } | |
231 | ||
4269bd1b | 232 | // ======================================================================= |
233 | // function : AddElement | |
234 | // purpose : | |
235 | // ======================================================================= | |
5322131b | 236 | void OpenGl_Group::AddElement (OpenGl_Element* theElem) |
2166f0fa | 237 | { |
e276548b | 238 | OpenGl_ElementNode *aNode = new OpenGl_ElementNode(); |
239 | ||
e276548b | 240 | aNode->elem = theElem; |
241 | aNode->next = NULL; | |
242 | (myLast? myLast->next : myFirst) = aNode; | |
243 | myLast = aNode; | |
244 | ||
4552cb85 | 245 | if (OpenGl_Raytrace::IsRaytracedElement (aNode) && !HasPersistence()) |
e276548b | 246 | { |
e276548b | 247 | myIsRaytracable = Standard_True; |
2166f0fa | 248 | |
b64d84be | 249 | OpenGl_Structure* aStruct = GlStruct(); |
250 | if (aStruct != NULL) | |
e276548b | 251 | { |
d4aaad5b | 252 | aStruct->UpdateStateIfRaytracable (Standard_False); |
e276548b | 253 | } |
254 | } | |
2166f0fa SK |
255 | } |
256 | ||
4552cb85 | 257 | // ======================================================================= |
258 | // function : renderFiltered | |
259 | // purpose : | |
260 | // ======================================================================= | |
261 | bool OpenGl_Group::renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, | |
262 | OpenGl_Element* theElement) const | |
263 | { | |
264 | if (!theWorkspace->ShouldRender (theElement, this)) | |
265 | { | |
266 | return false; | |
267 | } | |
268 | ||
269 | theElement->Render (theWorkspace); | |
270 | return true; | |
271 | } | |
272 | ||
4269bd1b | 273 | // ======================================================================= |
274 | // function : Render | |
275 | // purpose : | |
276 | // ======================================================================= | |
bf75be98 | 277 | void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const |
2166f0fa | 278 | { |
2166f0fa | 279 | // Setup aspects |
25c35042 | 280 | theWorkspace->SetAllowFaceCulling (myIsClosed |
281 | && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn()); | |
bf5f0ca2 | 282 | const OpenGl_Aspects* aBackAspects = theWorkspace->Aspects(); |
283 | const bool isAspectSet = myAspects != NULL && renderFiltered (theWorkspace, myAspects); | |
2166f0fa SK |
284 | |
285 | // Render group elements | |
bf75be98 | 286 | for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next) |
2166f0fa | 287 | { |
1b661a81 | 288 | renderFiltered (theWorkspace, aNodeIter->elem); |
2166f0fa SK |
289 | } |
290 | ||
291 | // Restore aspects | |
bf5f0ca2 | 292 | if (isAspectSet) |
293 | theWorkspace->SetAspects (aBackAspects); | |
2166f0fa SK |
294 | } |
295 | ||
b64d84be | 296 | // ======================================================================= |
297 | // function : Clear | |
298 | // purpose : | |
299 | // ======================================================================= | |
300 | void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr) | |
301 | { | |
302 | if (IsDeleted()) | |
303 | { | |
304 | return; | |
305 | } | |
306 | ||
307 | OpenGl_Structure* aStruct = GlStruct(); | |
308 | const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext(); | |
309 | ||
310 | Release (aCtx); | |
311 | Graphic3d_Group::Clear (theToUpdateStructureMgr); | |
d4aaad5b | 312 | |
313 | myIsRaytracable = Standard_False; | |
b64d84be | 314 | } |
315 | ||
4269bd1b | 316 | // ======================================================================= |
317 | // function : Release | |
318 | // purpose : | |
319 | // ======================================================================= | |
5e27df78 | 320 | void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx) |
321 | { | |
322 | // Delete elements | |
323 | while (myFirst != NULL) | |
324 | { | |
325 | OpenGl_ElementNode* aNext = myFirst->next; | |
ad67e367 | 326 | OpenGl_Element::Destroy (theGlCtx.get(), myFirst->elem); |
5e27df78 | 327 | delete myFirst; |
328 | myFirst = aNext; | |
329 | } | |
330 | myLast = NULL; | |
331 | ||
ad67e367 | 332 | OpenGl_Element::Destroy (theGlCtx.get(), myAspects); |
5e27df78 | 333 | } |
0904aa63 | 334 | |
335 | // ======================================================================= | |
336 | // function : DumpJson | |
337 | // purpose : | |
338 | // ======================================================================= | |
bc73b006 | 339 | void OpenGl_Group::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const |
0904aa63 | 340 | { |
bc73b006 | 341 | OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream) |
0904aa63 | 342 | |
bc73b006 | 343 | OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Graphic3d_Group) |
344 | ||
345 | OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myAspects) | |
346 | for (OpenGl_ElementNode* aNode = myFirst; aNode != NULL; aNode = aNode->next) | |
347 | { | |
348 | OpenGl_Element* anElement = aNode->elem; | |
349 | OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anElement) | |
350 | } | |
351 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsRaytracable) | |
0904aa63 | 352 | } |