0027818: Visualization - provide an interface to define highlight presentation properties
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
CommitLineData
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.
b311480e 15
4269bd1b 16#include <OpenGl_CappingAlgo.hxx>
17#include <OpenGl_Context.hxx>
30f0ad28 18#include <OpenGl_GlCore11.hxx>
63bcc448 19#include <OpenGl_GraphicDriver.hxx>
30f0ad28 20#include <OpenGl_ShaderManager.hxx>
21#include <OpenGl_ShaderProgram.hxx>
2bd4bfac 22#include <OpenGl_StructureShadow.hxx>
30f0ad28 23#include <OpenGl_Vec.hxx>
24#include <OpenGl_View.hxx>
25#include <OpenGl_Workspace.hxx>
2166f0fa 26
494782f6 27#include <Graphic3d_SequenceOfHClipPlane.hxx>
b859a34d 28
63bcc448 29
92efcf78 30IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure)
31
27eed937 32//! Auxiliary class for bounding box presentation
33class OpenGl_BndBoxPrs : public OpenGl_Element
34{
35
36public:
37
38 //! Main constructor
b7cd4ba7 39 OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox)
40 {
41 const float Xm = theBndBox.CornerMin().x();
42 const float Ym = theBndBox.CornerMin().y();
43 const float Zm = theBndBox.CornerMin().z();
44 const float XM = theBndBox.CornerMax().x();
45 const float YM = theBndBox.CornerMax().y();
46 const float ZM = theBndBox.CornerMax().z();
47
27eed937 48 myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
49 myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
50 myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
51 myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm);
52 myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm);
53 myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm);
54 myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM);
55 myVerts[7] = OpenGl_Vec3 (XM, YM, ZM);
56 myVerts[8] = OpenGl_Vec3 (XM, YM, Zm);
57 myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm);
58 myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
59 myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
60 myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
61 myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
62 myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
63 myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
64 }
65
66 //! Render presentation
67 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
68 {
ca3c13d1 69 #if !defined(GL_ES_VERSION_2_0)
27eed937 70 // Apply line aspect
27eed937 71 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
72
73 glDisable (GL_LIGHTING);
27eed937 74
75 // Use highlight colors
b6472664 76 theWorkspace->GetGlContext()->core11->glColor3fv (theWorkspace->LineColor().GetData());
27eed937 77
78 glEnableClientState (GL_VERTEX_ARRAY);
79 glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
80 glDrawArrays (GL_LINE_STRIP, 0, 16);
81 glDisableClientState (GL_VERTEX_ARRAY);
82
83 // restore aspects
84 if (!aPrevTexture.IsNull())
85 {
86 theWorkspace->EnableTexture (aPrevTexture);
87 }
20aeeb7b 88 #else
89 (void )theWorkspace;
ca3c13d1 90 #endif
27eed937 91 }
92
93 //! Release graphical resources
10b9c7df 94 virtual void Release (OpenGl_Context*)
27eed937 95 {
96 //
97 }
98
99protected:
100
101 //! Protected destructor
102 virtual ~OpenGl_BndBoxPrs() {}
103
104private:
105
106 OpenGl_Vec3 myVerts[16]; //!< vertices array
107
108public:
109
110 DEFINE_STANDARD_ALLOC
111
112};
2166f0fa
SK
113
114/*----------------------------------------------------------------------*/
115
4269bd1b 116// =======================================================================
4269bd1b 117// function : OpenGl_Structure
118// purpose :
119// =======================================================================
63bcc448 120OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
121: Graphic3d_CStructure (theManager),
d4aaad5b 122 myInstancedStructure (NULL),
123 myIsRaytracable (Standard_False),
124 myModificationState (0),
125 myIsCulled (Standard_True),
126 myIsMirrored (Standard_False)
2166f0fa 127{
a1954302 128 //
2166f0fa
SK
129}
130
4269bd1b 131// =======================================================================
132// function : ~OpenGl_Structure
133// purpose :
134// =======================================================================
5e27df78 135OpenGl_Structure::~OpenGl_Structure()
2166f0fa 136{
5e27df78 137 Release (Handle(OpenGl_Context)());
2166f0fa
SK
138}
139
4269bd1b 140// =======================================================================
1f7f5a90 141// function : SetTransformation
63bcc448 142// purpose :
143// =======================================================================
1f7f5a90 144void OpenGl_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf)
63bcc448 145{
1f7f5a90 146 myTrsf = theTrsf;
147 myIsMirrored = Standard_False;
148 if (!myTrsf.IsNull())
149 {
150 // Determinant of transform matrix less then 0 means that mirror transform applied.
151 const Standard_Real aDet = myTrsf->Value(1, 1) * (myTrsf->Value (2, 2) * myTrsf->Value (3, 3) - myTrsf->Value (3, 2) * myTrsf->Value (2, 3))
152 - myTrsf->Value(1, 2) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 3) - myTrsf->Value (3, 1) * myTrsf->Value (2, 3))
153 + myTrsf->Value(1, 3) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 2) - myTrsf->Value (3, 1) * myTrsf->Value (2, 2));
154 myIsMirrored = aDet < 0.0;
155 }
7d9e854b 156
d4aaad5b 157 if (IsRaytracable())
e276548b 158 {
d4aaad5b 159 ++myModificationState;
e276548b 160 }
2166f0fa
SK
161}
162
4269bd1b 163// =======================================================================
b64d84be 164// function : clearHighlightBox
4269bd1b 165// purpose :
166// =======================================================================
b64d84be 167void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 168{
b64d84be 169 if (!myHighlightBox.IsNull())
5e27df78 170 {
171 myHighlightBox->Release (theGlCtx);
b64d84be 172 myHighlightBox.Nullify();
2166f0fa
SK
173 }
174}
175
4269bd1b 176// =======================================================================
63bcc448 177// function : HighlightWithBndBox
178// purpose :
179// =======================================================================
8e5fb5ea 180void OpenGl_Structure::highlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct)
63bcc448 181{
7d9e854b 182 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
b64d84be 183
184 if (!myHighlightBox.IsNull())
185 {
7d9e854b 186 myHighlightBox->Release (aContext);
b64d84be 187 }
63bcc448 188 else
b64d84be 189 {
190 myHighlightBox = new OpenGl_Group (theStruct);
191 }
192
8e5fb5ea 193 myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myHighlightStyle->Color(), Aspect_TOL_SOLID, 1.0));
b64d84be 194
b7cd4ba7 195 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
b64d84be 196 myHighlightBox->AddElement (aBndBoxPrs);
63bcc448 197}
198
199// =======================================================================
8e5fb5ea 200// function : GraphicHighlight
4269bd1b 201// purpose :
202// =======================================================================
8e5fb5ea 203void OpenGl_Structure::GraphicHighlight (const Handle(Graphic3d_HighlightStyle)& theStyle,
204 const Handle(Graphic3d_Structure)& theStruct)
2166f0fa 205{
8e5fb5ea 206 myHighlightStyle = theStyle;
207
208 highlight = 1;
209 if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
b6472664 210 {
8e5fb5ea 211 highlightWithBndBox (theStruct);
5e27df78 212 }
2166f0fa
SK
213}
214
4269bd1b 215// =======================================================================
8e5fb5ea 216// function : GraphicUnhighlight
4269bd1b 217// purpose :
218// =======================================================================
8e5fb5ea 219void OpenGl_Structure::GraphicUnhighlight()
2166f0fa 220{
8e5fb5ea 221 highlight = 0;
222
223 if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
224 {
225 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
226 clearHighlightBox (aContext);
227 }
228
229 myHighlightStyle.Nullify();
2166f0fa
SK
230}
231
4269bd1b 232// =======================================================================
a1954302 233// function : OnVisibilityChanged
e276548b 234// purpose :
235// =======================================================================
a1954302 236void OpenGl_Structure::OnVisibilityChanged()
e276548b 237{
d4aaad5b 238 if (IsRaytracable())
e276548b 239 {
d4aaad5b 240 ++myModificationState;
e276548b 241 }
e276548b 242}
243
e276548b 244// =======================================================================
d4aaad5b 245// function : IsRaytracable
e276548b 246// purpose :
247// =======================================================================
d4aaad5b 248Standard_Boolean OpenGl_Structure::IsRaytracable() const
e276548b 249{
3e05329c 250 if (!myGroups.IsEmpty()
251 && myIsRaytracable)
e276548b 252 {
3e05329c 253 return Standard_True;
e276548b 254 }
d5af8626 255
3e05329c 256 return myInstancedStructure != NULL
257 && myInstancedStructure->IsRaytracable();
d5af8626 258}
259
260// =======================================================================
d4aaad5b 261// function : UpdateRaytracableState
e276548b 262// purpose :
263// =======================================================================
d4aaad5b 264void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
e276548b 265{
3e05329c 266 myIsRaytracable = !toCheck;
267 if (!myIsRaytracable)
268 {
269 for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next())
270 {
271 if (anIter.Value()->IsRaytracable())
272 {
273 myIsRaytracable = Standard_True;
274 break;
275 }
276 }
277 }
e276548b 278
d4aaad5b 279 if (IsRaytracable())
e276548b 280 {
d4aaad5b 281 ++myModificationState;
e276548b 282 }
283}
284
e276548b 285// =======================================================================
4269bd1b 286// function : Connect
287// purpose :
288// =======================================================================
63bcc448 289void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
2166f0fa 290{
d4aaad5b 291 OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
292
293 Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
294 "Error! Instanced structure is already defined");
295
296 myInstancedStructure = aStruct;
e276548b 297
63bcc448 298 if (aStruct->IsRaytracable())
e276548b 299 {
d4aaad5b 300 UpdateStateIfRaytracable (Standard_False);
e276548b 301 }
2166f0fa
SK
302}
303
4269bd1b 304// =======================================================================
305// function : Disconnect
306// purpose :
307// =======================================================================
63bcc448 308void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
2166f0fa 309{
d4aaad5b 310 OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
e276548b 311
d4aaad5b 312 if (myInstancedStructure == aStruct)
313 {
314 myInstancedStructure = NULL;
e276548b 315
d4aaad5b 316 if (aStruct->IsRaytracable())
317 {
318 UpdateStateIfRaytracable();
2166f0fa 319 }
2166f0fa
SK
320 }
321}
322
4269bd1b 323// =======================================================================
b64d84be 324// function : NewGroup
4269bd1b 325// purpose :
326// =======================================================================
b64d84be 327Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
2166f0fa 328{
b64d84be 329 Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
330 myGroups.Append (aGroup);
331 return aGroup;
2166f0fa
SK
332}
333
4269bd1b 334// =======================================================================
335// function : RemoveGroup
336// purpose :
337// =======================================================================
b64d84be 338void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
2166f0fa 339{
b64d84be 340 if (theGroup.IsNull())
341 {
342 return;
343 }
344
345 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
2166f0fa
SK
346 {
347 // Check for the given group
b64d84be 348 if (aGroupIter.Value() == theGroup)
2166f0fa 349 {
d4aaad5b 350 const Standard_Boolean wasRaytracable =
351 static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
352
b64d84be 353 theGroup->Clear (Standard_False);
e276548b 354
d4aaad5b 355 if (wasRaytracable)
e276548b 356 {
d4aaad5b 357 UpdateStateIfRaytracable();
e276548b 358 }
e276548b 359
b64d84be 360 myGroups.Remove (aGroupIter);
2166f0fa
SK
361 return;
362 }
2166f0fa
SK
363 }
364}
365
4269bd1b 366// =======================================================================
367// function : Clear
368// purpose :
369// =======================================================================
63bcc448 370void OpenGl_Structure::Clear()
371{
372 Clear (GlDriver()->GetSharedContext());
373}
374
375// =======================================================================
376// function : Clear
377// purpose :
378// =======================================================================
5e27df78 379void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 380{
e276548b 381 Standard_Boolean aRaytracableGroupDeleted (Standard_False);
e276548b 382
5e27df78 383 // Release groups
b64d84be 384 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
2166f0fa 385 {
b64d84be 386 aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
5322131b 387
2166f0fa 388 // Delete objects
b64d84be 389 aGroupIter.ChangeValue()->Release (theGlCtx);
2166f0fa
SK
390 }
391 myGroups.Clear();
e276548b 392
e276548b 393 if (aRaytracableGroupDeleted)
394 {
d4aaad5b 395 myIsRaytracable = Standard_False;
e276548b 396 }
b7cd4ba7 397
398 Is2dText = Standard_False;
399 IsForHighlight = Standard_False;
2166f0fa
SK
400}
401
4269bd1b 402// =======================================================================
cc6852f3 403// function : renderGeometry
0717ddc1 404// purpose :
405// =======================================================================
cc6852f3 406void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace,
407 bool& theHasClosed) const
0717ddc1 408{
cc6852f3 409 if (myInstancedStructure != NULL)
0717ddc1 410 {
cc6852f3 411 myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
412 }
413
414 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
415 {
416 theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
7d9e854b 417 aGroupIter.Value()->Render (theWorkspace);
0717ddc1 418 }
419}
cc6852f3 420
421// =======================================================================
4269bd1b 422// function : Render
423// purpose :
424// =======================================================================
7d9e854b 425void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
2166f0fa
SK
426{
427 // Process the structure only if visible
a1954302 428 if (!visible)
7d9e854b 429 {
2166f0fa 430 return;
7d9e854b 431 }
2166f0fa 432
c827ea3a 433 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
b7cd4ba7 434
2166f0fa 435 // Render named status
8e5fb5ea 436 if (highlight && myHighlightBox.IsNull())
a1954302 437 {
f9ba5c4d 438 theWorkspace->SetHighlight (true);
a1954302 439 }
2166f0fa 440
2166f0fa 441 // Apply local transformation
6bd94e0d 442 aCtx->ModelWorldState.Push();
1f7f5a90 443 OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
444 if (!myTrsf.IsNull())
445 {
446 myTrsf->Trsf().GetMat4 (aModelWorld);
447 }
448 else
449 {
450 aModelWorld.InitIdentity();
451 }
6bd94e0d 452
1d92133e 453 const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
454
455#if !defined(GL_ES_VERSION_2_0)
456 // detect scale transform
1f7f5a90 457 if (aCtx->core11 != NULL
458 && !myTrsf.IsNull())
1d92133e 459 {
1f7f5a90 460 const Standard_Real aScale = myTrsf->ScaleFactor();
461 if (Abs (aScale - 1.0) > Precision::Confusion())
1d92133e 462 {
463 aCtx->SetGlNormalizeEnabled (Standard_True);
464 }
465 }
466#endif
467
778cd667 468 if (!myTrsfPers.IsNull())
825aa485 469 {
778cd667 470 OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
471 myTrsfPers->Apply (theWorkspace->View()->Camera(), aCtx->ProjectionState.Current(), aWorldView,
472 aCtx->Viewport()[2], aCtx->Viewport()[3]);
2166f0fa 473
825aa485 474 aCtx->WorldViewState.Push();
825aa485 475 aCtx->WorldViewState.SetCurrent (aWorldView);
2166f0fa 476
1d92133e 477 #if !defined(GL_ES_VERSION_2_0)
478 if (!aCtx->IsGlNormalizeEnabled()
479 && aCtx->core11 != NULL)
480 {
481 const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
482 if (Abs (aScale - 1.0f) > Precision::Confusion())
483 {
484 aCtx->SetGlNormalizeEnabled (Standard_True);
485 }
486 }
487 #endif
04be5003 488 }
489
d437b80d 490 // Take into account transform persistence
491 aCtx->ApplyModelViewMatrix();
c827ea3a 492
f9ba5c4d 493 // remember aspects
494 const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->AspectLine();
495 const OpenGl_AspectFace* aPrevAspectFace = theWorkspace->AspectFace();
496 const OpenGl_AspectMarker* aPrevAspectMarker = theWorkspace->AspectMarker();
497 const OpenGl_AspectText* aPrevAspectText = theWorkspace->AspectText();
7d9e854b 498
499 // Apply correction for mirror transform
500 if (myIsMirrored)
501 {
c827ea3a 502 aCtx->core11fwd->glFrontFace (GL_CW);
7d9e854b 503 }
2166f0fa 504
2166f0fa 505 // Apply highlight color
b6472664 506 const OpenGl_Vec4* aHighlightColor = theWorkspace->HighlightColor;
8e5fb5ea 507 if (!myHighlightStyle.IsNull())
508 theWorkspace->HighlightColor = myHighlightStyle->ColorFltPtr();
2166f0fa 509
b859a34d 510 // Collect clipping planes of structure scope
3202bf1e 511 aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes);
4269bd1b 512
1a7ece8f 513 // True if structure is fully clipped
514 bool isClipped = false;
3202bf1e 515 bool hasDisabled = false;
516 if (aCtx->Clipping().IsClippingOrCappingOn())
1a7ece8f 517 {
3202bf1e 518 const Graphic3d_BndBox4f& aBBox = BoundingBox();
778cd667 519 if ((!myTrsfPers.IsNull() && myTrsfPers->IsTrihedronOr2d())
3202bf1e 520 || (!myClipPlanes.IsNull() && myClipPlanes->ToOverrideGlobal()))
1a7ece8f 521 {
3202bf1e 522 aCtx->ChangeClipping().DisableGlobal (aCtx);
523 hasDisabled = aCtx->Clipping().HasDisabled();
524 }
1a7ece8f 525
3202bf1e 526 // Set of clipping planes that do not intersect the structure,
527 // and thus can be disabled to improve rendering performance
528 if (aBBox.IsValid()
778cd667 529 && myTrsfPers.IsNull())
3202bf1e 530 {
531 for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
1a7ece8f 532 {
3202bf1e 533 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
534 if (!aPlane->IsOn())
535 {
536 continue;
537 }
1a7ece8f 538
3202bf1e 539 // check for clipping
540 const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
541 const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
542 aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
543 aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
544 1.0);
545 if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
546 {
547 isClipped = true;
548 break;
549 }
550
551 // check for no intersection (e.g. object is "entirely not clipped")
552 const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
553 aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
554 aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
555 1.0);
556 if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
1a7ece8f 557 {
3202bf1e 558 aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False);
559 hasDisabled = true;
1a7ece8f 560 }
1a7ece8f 561 }
562 }
3202bf1e 563
564 if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
565 || hasDisabled)
566 {
567 // Set OCCT state uniform variables
568 aCtx->ShaderManager()->UpdateClippingState();
569 }
1a7ece8f 570 }
571
2166f0fa 572 // Render groups
cc6852f3 573 bool hasClosedPrims = false;
1a7ece8f 574 if (!isClipped)
575 {
576 renderGeometry (theWorkspace, hasClosedPrims);
577 }
2166f0fa 578
7d9e854b 579 // Reset correction for mirror transform
580 if (myIsMirrored)
c827ea3a 581 {
582 aCtx->core11fwd->glFrontFace (GL_CCW);
583 }
7d9e854b 584
b859a34d 585 // Render capping for structure groups
cc6852f3 586 if (hasClosedPrims
1a7ece8f 587 && aCtx->Clipping().IsCappingOn())
b859a34d 588 {
cc6852f3 589 OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
b859a34d 590 }
4269bd1b 591
b859a34d 592 // Revert structure clippings
3202bf1e 593 if (hasDisabled)
1a7ece8f 594 {
595 // enable planes that were previously disabled
3202bf1e 596 aCtx->ChangeClipping().RestoreDisabled (aCtx);
1a7ece8f 597 }
3202bf1e 598 aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)());
599 if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
600 || hasDisabled)
4269bd1b 601 {
30f0ad28 602 // Set OCCT state uniform variables
deb02f86 603 aCtx->ShaderManager()->RevertClippingState();
4269bd1b 604 }
605
825aa485 606 // Restore local transformation
6bd94e0d 607 aCtx->ModelWorldState.Pop();
608 aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
778cd667 609 if (!myTrsfPers.IsNull())
825aa485 610 {
825aa485 611 aCtx->WorldViewState.Pop();
825aa485 612 }
c827ea3a 613
2166f0fa 614 // Restore highlight color
7d9e854b 615 theWorkspace->HighlightColor = aHighlightColor;
2166f0fa
SK
616
617 // Restore aspects
f9ba5c4d 618 theWorkspace->SetAspectLine (aPrevAspectLine);
619 theWorkspace->SetAspectFace (aPrevAspectFace);
620 theWorkspace->SetAspectMarker (aPrevAspectMarker);
621 theWorkspace->SetAspectText (aPrevAspectText);
2166f0fa 622
b7cd4ba7 623 // Apply highlight box
624 if (!myHighlightBox.IsNull())
625 {
7d9e854b 626 myHighlightBox->Render (theWorkspace);
b7cd4ba7 627 }
628
2166f0fa 629 // Restore named status
f9ba5c4d 630 theWorkspace->SetHighlight (false);
2166f0fa
SK
631}
632
5e27df78 633// =======================================================================
634// function : Release
635// purpose :
636// =======================================================================
637void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
638{
639 // Release groups
640 Clear (theGlCtx);
8e5fb5ea 641 clearHighlightBox (theGlCtx);
642 myHighlightStyle.Nullify();
5e27df78 643}
644
dd8a4ce9 645// =======================================================================
646// function : ReleaseGlResources
647// purpose :
648// =======================================================================
649void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
650{
b64d84be 651 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
dd8a4ce9 652 {
b64d84be 653 aGroupIter.ChangeValue()->Release (theGlCtx);
dd8a4ce9 654 }
b64d84be 655 if (!myHighlightBox.IsNull())
dd8a4ce9 656 {
10b9c7df 657 myHighlightBox->Release (theGlCtx.operator->());
dd8a4ce9 658 }
659}
660
59f45b7c 661//=======================================================================
679ecdee 662//function : ShadowLink
663//purpose :
664//=======================================================================
665Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
666{
667 return new OpenGl_StructureShadow (theManager, this);
668}