0022582: Visualization - provide an API for dumping a sub-region of the viewport
[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// =======================================================================
117// function : OpenGl_Structure
118// purpose :
119// =======================================================================
63bcc448 120OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
121: Graphic3d_CStructure (theManager),
d4aaad5b 122 myHighlightColor (NULL),
123 myInstancedStructure (NULL),
124 myIsRaytracable (Standard_False),
125 myModificationState (0),
126 myIsCulled (Standard_True),
127 myIsMirrored (Standard_False)
2166f0fa 128{
a1954302 129 //
2166f0fa
SK
130}
131
4269bd1b 132// =======================================================================
133// function : ~OpenGl_Structure
134// purpose :
135// =======================================================================
5e27df78 136OpenGl_Structure::~OpenGl_Structure()
2166f0fa 137{
5e27df78 138 Release (Handle(OpenGl_Context)());
2166f0fa
SK
139}
140
63bcc448 141// =======================================================================
142// function : UpdateTransformation
143// purpose :
144// =======================================================================
145void OpenGl_Structure::UpdateTransformation()
146{
6bd94e0d 147 const OpenGl_Mat4& aMat = Graphic3d_CStructure::Transformation;
7d9e854b 148 Standard_ShortReal aDet =
6bd94e0d 149 aMat.GetValue(0, 0) * (aMat.GetValue(1, 1) * aMat.GetValue(2, 2) - aMat.GetValue(2, 1) * aMat.GetValue(1, 2)) -
150 aMat.GetValue(0, 1) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 2) - aMat.GetValue(2, 0) * aMat.GetValue(1, 2)) +
151 aMat.GetValue(0, 2) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 1) - aMat.GetValue(2, 0) * aMat.GetValue(1, 1));
7d9e854b 152
153 // Determinant of transform matrix less then 0 means that mirror transform applied.
154 myIsMirrored = aDet < 0.0f;
155
d4aaad5b 156 if (IsRaytracable())
e276548b 157 {
d4aaad5b 158 ++myModificationState;
e276548b 159 }
2166f0fa
SK
160}
161
4269bd1b 162// =======================================================================
b64d84be 163// function : clearHighlightBox
4269bd1b 164// purpose :
165// =======================================================================
b64d84be 166void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 167{
b64d84be 168 if (!myHighlightBox.IsNull())
5e27df78 169 {
170 myHighlightBox->Release (theGlCtx);
b64d84be 171 myHighlightBox.Nullify();
2166f0fa
SK
172 }
173}
174
63bcc448 175// =======================================================================
176// function : HighlightWithColor
177// purpose :
178// =======================================================================
179void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3& theColor,
180 const Standard_Boolean theToCreate)
181{
7d9e854b 182 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
63bcc448 183 if (theToCreate)
7d9e854b 184 setHighlightColor (aContext, theColor);
63bcc448 185 else
7d9e854b 186 clearHighlightColor (aContext);
63bcc448 187}
188
189// =======================================================================
190// function : HighlightWithBndBox
191// purpose :
192// =======================================================================
b64d84be 193void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct,
194 const Standard_Boolean theToCreate)
63bcc448 195{
7d9e854b 196 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
b64d84be 197 if (!theToCreate)
198 {
7d9e854b 199 clearHighlightBox (aContext);
b64d84be 200 return;
201 }
202
203 if (!myHighlightBox.IsNull())
204 {
7d9e854b 205 myHighlightBox->Release (aContext);
b64d84be 206 }
63bcc448 207 else
b64d84be 208 {
209 myHighlightBox = new OpenGl_Group (theStruct);
210 }
211
b6472664 212 myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (HighlightColor, Aspect_TOL_SOLID, 1.0));
b64d84be 213
b7cd4ba7 214 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
b64d84be 215 myHighlightBox->AddElement (aBndBoxPrs);
63bcc448 216}
217
4269bd1b 218// =======================================================================
b64d84be 219// function : setHighlightColor
4269bd1b 220// purpose :
221// =======================================================================
b64d84be 222void OpenGl_Structure::setHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
63bcc448 223 const Graphic3d_Vec3& theColor)
2166f0fa 224{
b64d84be 225 clearHighlightBox (theGlCtx);
5e27df78 226 if (myHighlightColor == NULL)
227 {
b6472664 228 myHighlightColor = new OpenGl_Vec4 (theColor, 1.0f);
229 }
230 else
231 {
232 myHighlightColor->xyz() = theColor;
5e27df78 233 }
2166f0fa
SK
234}
235
4269bd1b 236// =======================================================================
b64d84be 237// function : clearHighlightColor
4269bd1b 238// purpose :
239// =======================================================================
b64d84be 240void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 241{
b64d84be 242 clearHighlightBox(theGlCtx);
5e27df78 243 delete myHighlightColor;
244 myHighlightColor = NULL;
2166f0fa
SK
245}
246
e276548b 247// =======================================================================
a1954302 248// function : OnVisibilityChanged
e276548b 249// purpose :
250// =======================================================================
a1954302 251void OpenGl_Structure::OnVisibilityChanged()
e276548b 252{
d4aaad5b 253 if (IsRaytracable())
e276548b 254 {
d4aaad5b 255 ++myModificationState;
e276548b 256 }
e276548b 257}
258
e276548b 259// =======================================================================
d4aaad5b 260// function : IsRaytracable
e276548b 261// purpose :
262// =======================================================================
d4aaad5b 263Standard_Boolean OpenGl_Structure::IsRaytracable() const
e276548b 264{
3e05329c 265 if (!myGroups.IsEmpty()
266 && myIsRaytracable)
e276548b 267 {
3e05329c 268 return Standard_True;
e276548b 269 }
d5af8626 270
3e05329c 271 return myInstancedStructure != NULL
272 && myInstancedStructure->IsRaytracable();
d5af8626 273}
274
e276548b 275// =======================================================================
d4aaad5b 276// function : UpdateRaytracableState
e276548b 277// purpose :
278// =======================================================================
d4aaad5b 279void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
e276548b 280{
3e05329c 281 myIsRaytracable = !toCheck;
282 if (!myIsRaytracable)
283 {
284 for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next())
285 {
286 if (anIter.Value()->IsRaytracable())
287 {
288 myIsRaytracable = Standard_True;
289 break;
290 }
291 }
292 }
e276548b 293
d4aaad5b 294 if (IsRaytracable())
e276548b 295 {
d4aaad5b 296 ++myModificationState;
e276548b 297 }
298}
299
4269bd1b 300// =======================================================================
301// function : Connect
302// purpose :
303// =======================================================================
63bcc448 304void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
2166f0fa 305{
d4aaad5b 306 OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
307
308 Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
309 "Error! Instanced structure is already defined");
310
311 myInstancedStructure = aStruct;
e276548b 312
63bcc448 313 if (aStruct->IsRaytracable())
e276548b 314 {
d4aaad5b 315 UpdateStateIfRaytracable (Standard_False);
e276548b 316 }
2166f0fa
SK
317}
318
4269bd1b 319// =======================================================================
320// function : Disconnect
321// purpose :
322// =======================================================================
63bcc448 323void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
2166f0fa 324{
d4aaad5b 325 OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
e276548b 326
d4aaad5b 327 if (myInstancedStructure == aStruct)
328 {
329 myInstancedStructure = NULL;
e276548b 330
d4aaad5b 331 if (aStruct->IsRaytracable())
332 {
333 UpdateStateIfRaytracable();
2166f0fa 334 }
2166f0fa
SK
335 }
336}
337
4269bd1b 338// =======================================================================
b64d84be 339// function : NewGroup
4269bd1b 340// purpose :
341// =======================================================================
b64d84be 342Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
2166f0fa 343{
b64d84be 344 Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
345 myGroups.Append (aGroup);
346 return aGroup;
2166f0fa
SK
347}
348
4269bd1b 349// =======================================================================
350// function : RemoveGroup
351// purpose :
352// =======================================================================
b64d84be 353void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
2166f0fa 354{
b64d84be 355 if (theGroup.IsNull())
356 {
357 return;
358 }
359
360 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
2166f0fa
SK
361 {
362 // Check for the given group
b64d84be 363 if (aGroupIter.Value() == theGroup)
2166f0fa 364 {
d4aaad5b 365 const Standard_Boolean wasRaytracable =
366 static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
367
b64d84be 368 theGroup->Clear (Standard_False);
e276548b 369
d4aaad5b 370 if (wasRaytracable)
e276548b 371 {
d4aaad5b 372 UpdateStateIfRaytracable();
e276548b 373 }
e276548b 374
b64d84be 375 myGroups.Remove (aGroupIter);
2166f0fa
SK
376 return;
377 }
2166f0fa
SK
378 }
379}
380
63bcc448 381// =======================================================================
382// function : Clear
383// purpose :
384// =======================================================================
385void OpenGl_Structure::Clear()
386{
387 Clear (GlDriver()->GetSharedContext());
388}
389
4269bd1b 390// =======================================================================
391// function : Clear
392// purpose :
393// =======================================================================
5e27df78 394void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 395{
e276548b 396 Standard_Boolean aRaytracableGroupDeleted (Standard_False);
e276548b 397
5e27df78 398 // Release groups
b64d84be 399 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
2166f0fa 400 {
b64d84be 401 aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
5322131b 402
2166f0fa 403 // Delete objects
b64d84be 404 aGroupIter.ChangeValue()->Release (theGlCtx);
2166f0fa
SK
405 }
406 myGroups.Clear();
e276548b 407
e276548b 408 if (aRaytracableGroupDeleted)
409 {
d4aaad5b 410 myIsRaytracable = Standard_False;
e276548b 411 }
b7cd4ba7 412
413 Is2dText = Standard_False;
414 IsForHighlight = Standard_False;
2166f0fa
SK
415}
416
0717ddc1 417// =======================================================================
cc6852f3 418// function : renderGeometry
0717ddc1 419// purpose :
420// =======================================================================
cc6852f3 421void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace,
422 bool& theHasClosed) const
0717ddc1 423{
cc6852f3 424 if (myInstancedStructure != NULL)
0717ddc1 425 {
cc6852f3 426 myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
427 }
428
429 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
430 {
431 theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
7d9e854b 432 aGroupIter.Value()->Render (theWorkspace);
0717ddc1 433 }
434}
cc6852f3 435
4269bd1b 436// =======================================================================
437// function : Render
438// purpose :
439// =======================================================================
7d9e854b 440void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
2166f0fa
SK
441{
442 // Process the structure only if visible
a1954302 443 if (!visible)
7d9e854b 444 {
2166f0fa 445 return;
7d9e854b 446 }
2166f0fa 447
c827ea3a 448 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
b7cd4ba7 449
2166f0fa 450 // Render named status
a1954302 451 if (highlight)
452 {
f9ba5c4d 453 theWorkspace->SetHighlight (true);
a1954302 454 }
2166f0fa 455
2166f0fa 456 // Apply local transformation
6bd94e0d 457 aCtx->ModelWorldState.Push();
458 aCtx->ModelWorldState.SetCurrent (Transformation);
459
1d92133e 460 const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
461
462#if !defined(GL_ES_VERSION_2_0)
463 // detect scale transform
464 if (aCtx->core11 != NULL)
465 {
466 const Standard_ShortReal aScaleX = Transformation.GetRow (0).xyz().SquareModulus();
467 if (Abs (aScaleX - 1.f) > Precision::Confusion())
468 {
469 aCtx->SetGlNormalizeEnabled (Standard_True);
470 }
471 }
472#endif
473
825aa485 474 if (TransformPersistence.Flags)
475 {
476 OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
477 OpenGl_Mat4 aWorldView = aCtx->WorldViewState.Current();
3bffef55 478 TransformPersistence.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView,
479 aCtx->Viewport()[2], aCtx->Viewport()[3]);
2166f0fa 480
825aa485 481 aCtx->ProjectionState.Push();
482 aCtx->WorldViewState.Push();
483 aCtx->ProjectionState.SetCurrent (aProjection);
484 aCtx->WorldViewState.SetCurrent (aWorldView);
485 aCtx->ApplyProjectionMatrix();
2166f0fa 486
1d92133e 487 #if !defined(GL_ES_VERSION_2_0)
488 if (!aCtx->IsGlNormalizeEnabled()
489 && aCtx->core11 != NULL)
490 {
491 const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
492 if (Abs (aScale - 1.0f) > Precision::Confusion())
493 {
494 aCtx->SetGlNormalizeEnabled (Standard_True);
495 }
496 }
497 #endif
04be5003 498 }
499
d437b80d 500 // Take into account transform persistence
501 aCtx->ApplyModelViewMatrix();
c827ea3a 502
f9ba5c4d 503 // remember aspects
504 const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->AspectLine();
505 const OpenGl_AspectFace* aPrevAspectFace = theWorkspace->AspectFace();
506 const OpenGl_AspectMarker* aPrevAspectMarker = theWorkspace->AspectMarker();
507 const OpenGl_AspectText* aPrevAspectText = theWorkspace->AspectText();
7d9e854b 508
509 // Apply correction for mirror transform
510 if (myIsMirrored)
511 {
c827ea3a 512 aCtx->core11fwd->glFrontFace (GL_CW);
7d9e854b 513 }
2166f0fa 514
2166f0fa 515 // Apply highlight color
b6472664 516 const OpenGl_Vec4* aHighlightColor = theWorkspace->HighlightColor;
2166f0fa 517 if (myHighlightColor)
7d9e854b 518 theWorkspace->HighlightColor = myHighlightColor;
2166f0fa 519
4269bd1b 520 // Set up plane equations for non-structure transformed global model-view matrix
b859a34d 521 // List of planes to be applied to context state
1a7ece8f 522 Handle(NCollection_Shared<Graphic3d_SequenceOfHClipPlane>) aUserPlanes, aDisabledPlanes;
b859a34d 523
524 // Collect clipping planes of structure scope
525 if (!myClipPlanes.IsEmpty())
4269bd1b 526 {
1a7ece8f 527 for (Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes); aClippingIter.More(); aClippingIter.Next())
b859a34d 528 {
7d9e854b 529 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
b859a34d 530 if (!aClipPlane->IsOn())
531 {
532 continue;
533 }
534
535 if (aUserPlanes.IsNull())
536 {
1a7ece8f 537 aUserPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
b859a34d 538 }
51b10cd4 539 aUserPlanes->Append (aClipPlane);
b859a34d 540 }
4269bd1b 541 }
1a7ece8f 542 if (!aUserPlanes.IsNull())
4269bd1b 543 {
b859a34d 544 // add planes at loaded view matrix state
79f4f036 545 aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
30f0ad28 546
547 // Set OCCT state uniform variables
deb02f86 548 aCtx->ShaderManager()->UpdateClippingState();
4269bd1b 549 }
550
1a7ece8f 551 // True if structure is fully clipped
552 bool isClipped = false;
553
554 // Set of clipping planes that do not intersect the structure,
555 // and thus can be disabled to improve rendering performance
556 const Graphic3d_BndBox4f& aBBox = BoundingBox();
557 if (!aCtx->Clipping().Planes().IsEmpty() && aBBox.IsValid() && TransformPersistence.Flags == Graphic3d_TMF_None)
558 {
559 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aCtx->Clipping().Planes()); aPlaneIt.More(); aPlaneIt.Next())
560 {
561 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
562 if (!aPlane->IsOn())
563 {
564 continue;
565 }
566
567 // check for clipping
568 const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
569 const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
570 aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
571 aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
572 1.0);
573 if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
574 {
575 isClipped = true;
576 break;
577 }
578
579 // check for no intersection (e.g. object is "entirely not clipped")
580 const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
581 aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
582 aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
583 1.0);
584 if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
585 {
586 aCtx->ChangeClipping().SetEnabled (aCtx, aPlane, Standard_False);
587 if (aDisabledPlanes.IsNull())
588 {
589 aDisabledPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
590 if (aUserPlanes.IsNull())
591 {
592 aCtx->ShaderManager()->UpdateClippingState();
593 }
594 }
595 aDisabledPlanes->Append (aPlane);
596 }
597 }
598 }
599
2166f0fa 600 // Render groups
cc6852f3 601 bool hasClosedPrims = false;
1a7ece8f 602 if (!isClipped)
603 {
604 renderGeometry (theWorkspace, hasClosedPrims);
605 }
2166f0fa 606
7d9e854b 607 // Reset correction for mirror transform
608 if (myIsMirrored)
c827ea3a 609 {
610 aCtx->core11fwd->glFrontFace (GL_CCW);
611 }
7d9e854b 612
b859a34d 613 // Render capping for structure groups
cc6852f3 614 if (hasClosedPrims
1a7ece8f 615 && aCtx->Clipping().IsCappingOn())
b859a34d 616 {
cc6852f3 617 OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
b859a34d 618 }
4269bd1b 619
b859a34d 620 // Revert structure clippings
1a7ece8f 621 if (!aDisabledPlanes.IsNull())
622 {
623 // enable planes that were previously disabled
624 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aDisabledPlanes); aPlaneIt.More(); aPlaneIt.Next())
625 {
626 aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt.Value(), Standard_True);
627 }
628 if (aUserPlanes.IsNull())
629 {
630 aCtx->ShaderManager()->RevertClippingState();
631 }
632 }
633 if (!aUserPlanes.IsNull())
4269bd1b 634 {
79f4f036 635 aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);
30f0ad28 636
637 // Set OCCT state uniform variables
deb02f86 638 aCtx->ShaderManager()->RevertClippingState();
4269bd1b 639 }
640
825aa485 641 // Restore local transformation
6bd94e0d 642 aCtx->ModelWorldState.Pop();
643 aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
825aa485 644 if (TransformPersistence.Flags)
645 {
646 aCtx->ProjectionState.Pop();
647 aCtx->WorldViewState.Pop();
648 aCtx->ApplyProjectionMatrix();
649 }
c827ea3a 650
2166f0fa 651 // Restore highlight color
7d9e854b 652 theWorkspace->HighlightColor = aHighlightColor;
2166f0fa
SK
653
654 // Restore aspects
f9ba5c4d 655 theWorkspace->SetAspectLine (aPrevAspectLine);
656 theWorkspace->SetAspectFace (aPrevAspectFace);
657 theWorkspace->SetAspectMarker (aPrevAspectMarker);
658 theWorkspace->SetAspectText (aPrevAspectText);
2166f0fa 659
b7cd4ba7 660 // Apply highlight box
661 if (!myHighlightBox.IsNull())
662 {
7d9e854b 663 myHighlightBox->Render (theWorkspace);
b7cd4ba7 664 }
665
2166f0fa 666 // Restore named status
f9ba5c4d 667 theWorkspace->SetHighlight (false);
2166f0fa
SK
668}
669
5e27df78 670// =======================================================================
671// function : Release
672// purpose :
673// =======================================================================
674void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
675{
676 // Release groups
677 Clear (theGlCtx);
b64d84be 678 clearHighlightColor (theGlCtx);
5e27df78 679}
680
dd8a4ce9 681// =======================================================================
682// function : ReleaseGlResources
683// purpose :
684// =======================================================================
685void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
686{
b64d84be 687 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
dd8a4ce9 688 {
b64d84be 689 aGroupIter.ChangeValue()->Release (theGlCtx);
dd8a4ce9 690 }
b64d84be 691 if (!myHighlightBox.IsNull())
dd8a4ce9 692 {
10b9c7df 693 myHighlightBox->Release (theGlCtx.operator->());
dd8a4ce9 694 }
695}
696
679ecdee 697//=======================================================================
698//function : ShadowLink
699//purpose :
700//=======================================================================
701Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
702{
703 return new OpenGl_StructureShadow (theManager, this);
704}