0025695: Visualization, AIS_InteractiveContext - define default HilightMode
[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
7c3ef2f7 39 OpenGl_BndBoxPrs (const Graphic3d_BndBox3d& theBndBox)
b7cd4ba7 40 {
7c3ef2f7 41 const float Xm = (float )theBndBox.CornerMin().x();
42 const float Ym = (float)theBndBox.CornerMin().y();
43 const float Zm = (float)theBndBox.CornerMin().z();
44 const float XM = (float)theBndBox.CornerMax().x();
45 const float YM = (float)theBndBox.CornerMax().y();
46 const float ZM = (float)theBndBox.CornerMax().z();
b7cd4ba7 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{
7c3ef2f7 128 updateLayerTransformation();
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// =======================================================================
7c3ef2f7 141// function : SetZLayer
142// purpose :
143// =======================================================================
144void OpenGl_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerIndex)
145{
146 Graphic3d_CStructure::SetZLayer (theLayerIndex);
147 updateLayerTransformation();
148}
149
150// =======================================================================
1f7f5a90 151// function : SetTransformation
63bcc448 152// purpose :
153// =======================================================================
1f7f5a90 154void OpenGl_Structure::SetTransformation (const Handle(Geom_Transformation)& theTrsf)
63bcc448 155{
1f7f5a90 156 myTrsf = theTrsf;
157 myIsMirrored = Standard_False;
158 if (!myTrsf.IsNull())
159 {
160 // Determinant of transform matrix less then 0 means that mirror transform applied.
161 const Standard_Real aDet = myTrsf->Value(1, 1) * (myTrsf->Value (2, 2) * myTrsf->Value (3, 3) - myTrsf->Value (3, 2) * myTrsf->Value (2, 3))
162 - myTrsf->Value(1, 2) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 3) - myTrsf->Value (3, 1) * myTrsf->Value (2, 3))
163 + myTrsf->Value(1, 3) * (myTrsf->Value (2, 1) * myTrsf->Value (3, 2) - myTrsf->Value (3, 1) * myTrsf->Value (2, 2));
164 myIsMirrored = aDet < 0.0;
165 }
7d9e854b 166
7c3ef2f7 167 updateLayerTransformation();
d4aaad5b 168 if (IsRaytracable())
e276548b 169 {
d4aaad5b 170 ++myModificationState;
e276548b 171 }
2166f0fa
SK
172}
173
4269bd1b 174// =======================================================================
7c3ef2f7 175// function : SetTransformPersistence
176// purpose :
177// =======================================================================
178void OpenGl_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
179{
180 myTrsfPers = theTrsfPers;
181 updateLayerTransformation();
182}
183
184// =======================================================================
185// function : updateLayerTransformation
186// purpose :
187// =======================================================================
188void OpenGl_Structure::updateLayerTransformation()
189{
190 gp_Trsf aRenderTrsf;
191 if (!myTrsf.IsNull())
192 {
193 aRenderTrsf = myTrsf->Trsf();
194 }
195
196 const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
197 if (!aLayer.OriginTransformation().IsNull()
198 && myTrsfPers.IsNull())
199 {
200 aRenderTrsf.SetTranslationPart (aRenderTrsf.TranslationPart() - aLayer.Origin());
201 }
202 aRenderTrsf.GetMat4 (myRenderTrsf);
203}
204
205// =======================================================================
b64d84be 206// function : clearHighlightBox
4269bd1b 207// purpose :
208// =======================================================================
b64d84be 209void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 210{
b64d84be 211 if (!myHighlightBox.IsNull())
5e27df78 212 {
213 myHighlightBox->Release (theGlCtx);
b64d84be 214 myHighlightBox.Nullify();
2166f0fa
SK
215 }
216}
217
4269bd1b 218// =======================================================================
63bcc448 219// function : HighlightWithBndBox
220// purpose :
221// =======================================================================
8e5fb5ea 222void OpenGl_Structure::highlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct)
63bcc448 223{
7d9e854b 224 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
b64d84be 225
226 if (!myHighlightBox.IsNull())
227 {
7d9e854b 228 myHighlightBox->Release (aContext);
b64d84be 229 }
63bcc448 230 else
b64d84be 231 {
232 myHighlightBox = new OpenGl_Group (theStruct);
233 }
234
8e5fb5ea 235 myHighlightBox->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myHighlightStyle->Color(), Aspect_TOL_SOLID, 1.0));
b64d84be 236
b7cd4ba7 237 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
b64d84be 238 myHighlightBox->AddElement (aBndBoxPrs);
63bcc448 239}
240
241// =======================================================================
8e5fb5ea 242// function : GraphicHighlight
4269bd1b 243// purpose :
244// =======================================================================
f838dac4 245void OpenGl_Structure::GraphicHighlight (const Handle(Graphic3d_PresentationAttributes)& theStyle,
246 const Handle(Graphic3d_Structure)& theStruct)
2166f0fa 247{
424392e0 248 if (!myHighlightStyle.IsNull()
249 && myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX
250 && theStyle->Method() != Aspect_TOHM_BOUNDBOX)
251 {
252 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
253 clearHighlightBox (aContext);
254 }
255
8e5fb5ea 256 myHighlightStyle = theStyle;
257
258 highlight = 1;
259 if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
b6472664 260 {
8e5fb5ea 261 highlightWithBndBox (theStruct);
5e27df78 262 }
2166f0fa
SK
263}
264
4269bd1b 265// =======================================================================
8e5fb5ea 266// function : GraphicUnhighlight
4269bd1b 267// purpose :
268// =======================================================================
8e5fb5ea 269void OpenGl_Structure::GraphicUnhighlight()
2166f0fa 270{
8e5fb5ea 271 highlight = 0;
272
273 if (myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
274 {
275 const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
276 clearHighlightBox (aContext);
277 }
278
279 myHighlightStyle.Nullify();
2166f0fa
SK
280}
281
4269bd1b 282// =======================================================================
a1954302 283// function : OnVisibilityChanged
e276548b 284// purpose :
285// =======================================================================
a1954302 286void OpenGl_Structure::OnVisibilityChanged()
e276548b 287{
d4aaad5b 288 if (IsRaytracable())
e276548b 289 {
d4aaad5b 290 ++myModificationState;
e276548b 291 }
e276548b 292}
293
e276548b 294// =======================================================================
d4aaad5b 295// function : IsRaytracable
e276548b 296// purpose :
297// =======================================================================
d4aaad5b 298Standard_Boolean OpenGl_Structure::IsRaytracable() const
e276548b 299{
3e05329c 300 if (!myGroups.IsEmpty()
301 && myIsRaytracable)
e276548b 302 {
3e05329c 303 return Standard_True;
e276548b 304 }
d5af8626 305
3e05329c 306 return myInstancedStructure != NULL
307 && myInstancedStructure->IsRaytracable();
d5af8626 308}
309
310// =======================================================================
d4aaad5b 311// function : UpdateRaytracableState
e276548b 312// purpose :
313// =======================================================================
d4aaad5b 314void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
e276548b 315{
3e05329c 316 myIsRaytracable = !toCheck;
317 if (!myIsRaytracable)
318 {
319 for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next())
320 {
321 if (anIter.Value()->IsRaytracable())
322 {
323 myIsRaytracable = Standard_True;
324 break;
325 }
326 }
327 }
e276548b 328
d4aaad5b 329 if (IsRaytracable())
e276548b 330 {
d4aaad5b 331 ++myModificationState;
e276548b 332 }
333}
334
e276548b 335// =======================================================================
4269bd1b 336// function : Connect
337// purpose :
338// =======================================================================
63bcc448 339void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
2166f0fa 340{
d4aaad5b 341 OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
342
343 Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
344 "Error! Instanced structure is already defined");
345
346 myInstancedStructure = aStruct;
e276548b 347
63bcc448 348 if (aStruct->IsRaytracable())
e276548b 349 {
d4aaad5b 350 UpdateStateIfRaytracable (Standard_False);
e276548b 351 }
2166f0fa
SK
352}
353
4269bd1b 354// =======================================================================
355// function : Disconnect
356// purpose :
357// =======================================================================
63bcc448 358void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
2166f0fa 359{
d4aaad5b 360 OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
e276548b 361
d4aaad5b 362 if (myInstancedStructure == aStruct)
363 {
364 myInstancedStructure = NULL;
e276548b 365
d4aaad5b 366 if (aStruct->IsRaytracable())
367 {
368 UpdateStateIfRaytracable();
2166f0fa 369 }
2166f0fa
SK
370 }
371}
372
4269bd1b 373// =======================================================================
b64d84be 374// function : NewGroup
4269bd1b 375// purpose :
376// =======================================================================
b64d84be 377Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
2166f0fa 378{
b64d84be 379 Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
380 myGroups.Append (aGroup);
381 return aGroup;
2166f0fa
SK
382}
383
4269bd1b 384// =======================================================================
385// function : RemoveGroup
386// purpose :
387// =======================================================================
b64d84be 388void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
2166f0fa 389{
b64d84be 390 if (theGroup.IsNull())
391 {
392 return;
393 }
394
395 for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
2166f0fa
SK
396 {
397 // Check for the given group
b64d84be 398 if (aGroupIter.Value() == theGroup)
2166f0fa 399 {
d4aaad5b 400 const Standard_Boolean wasRaytracable =
401 static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
402
b64d84be 403 theGroup->Clear (Standard_False);
e276548b 404
d4aaad5b 405 if (wasRaytracable)
e276548b 406 {
d4aaad5b 407 UpdateStateIfRaytracable();
e276548b 408 }
e276548b 409
b64d84be 410 myGroups.Remove (aGroupIter);
2166f0fa
SK
411 return;
412 }
2166f0fa
SK
413 }
414}
415
4269bd1b 416// =======================================================================
417// function : Clear
418// purpose :
419// =======================================================================
63bcc448 420void OpenGl_Structure::Clear()
421{
422 Clear (GlDriver()->GetSharedContext());
423}
424
425// =======================================================================
426// function : Clear
427// purpose :
428// =======================================================================
5e27df78 429void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 430{
e276548b 431 Standard_Boolean aRaytracableGroupDeleted (Standard_False);
e276548b 432
5e27df78 433 // Release groups
b64d84be 434 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
2166f0fa 435 {
b64d84be 436 aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
5322131b 437
2166f0fa 438 // Delete objects
b64d84be 439 aGroupIter.ChangeValue()->Release (theGlCtx);
2166f0fa
SK
440 }
441 myGroups.Clear();
e276548b 442
e276548b 443 if (aRaytracableGroupDeleted)
444 {
d4aaad5b 445 myIsRaytracable = Standard_False;
e276548b 446 }
b7cd4ba7 447
448 Is2dText = Standard_False;
449 IsForHighlight = Standard_False;
2166f0fa
SK
450}
451
4269bd1b 452// =======================================================================
cc6852f3 453// function : renderGeometry
0717ddc1 454// purpose :
455// =======================================================================
cc6852f3 456void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace,
457 bool& theHasClosed) const
0717ddc1 458{
cc6852f3 459 if (myInstancedStructure != NULL)
0717ddc1 460 {
cc6852f3 461 myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
462 }
463
464 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
465 {
466 theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
7d9e854b 467 aGroupIter.Value()->Render (theWorkspace);
0717ddc1 468 }
469}
cc6852f3 470
471// =======================================================================
4269bd1b 472// function : Render
473// purpose :
474// =======================================================================
7d9e854b 475void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
2166f0fa
SK
476{
477 // Process the structure only if visible
a1954302 478 if (!visible)
7d9e854b 479 {
2166f0fa 480 return;
7d9e854b 481 }
2166f0fa 482
c827ea3a 483 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
b7cd4ba7 484
2166f0fa 485 // Render named status
8e5fb5ea 486 if (highlight && myHighlightBox.IsNull())
a1954302 487 {
f838dac4 488 theWorkspace->SetHighlightStyle (myHighlightStyle);
a1954302 489 }
2166f0fa 490
2166f0fa 491 // Apply local transformation
6bd94e0d 492 aCtx->ModelWorldState.Push();
1f7f5a90 493 OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
7c3ef2f7 494 aModelWorld = myRenderTrsf;
6bd94e0d 495
1d92133e 496 const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
1d92133e 497#if !defined(GL_ES_VERSION_2_0)
498 // detect scale transform
1f7f5a90 499 if (aCtx->core11 != NULL
500 && !myTrsf.IsNull())
1d92133e 501 {
1f7f5a90 502 const Standard_Real aScale = myTrsf->ScaleFactor();
503 if (Abs (aScale - 1.0) > Precision::Confusion())
1d92133e 504 {
505 aCtx->SetGlNormalizeEnabled (Standard_True);
506 }
507 }
508#endif
509
778cd667 510 if (!myTrsfPers.IsNull())
825aa485 511 {
825aa485 512 aCtx->WorldViewState.Push();
7c3ef2f7 513 OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
514 myTrsfPers->Apply (theWorkspace->View()->Camera(),
515 aCtx->ProjectionState.Current(), aWorldView,
516 aCtx->Viewport()[2], aCtx->Viewport()[3]);
2166f0fa 517
1d92133e 518 #if !defined(GL_ES_VERSION_2_0)
519 if (!aCtx->IsGlNormalizeEnabled()
520 && aCtx->core11 != NULL)
521 {
522 const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
7c3ef2f7 523 if (Abs (aScale - 1.0) > Precision::Confusion())
1d92133e 524 {
525 aCtx->SetGlNormalizeEnabled (Standard_True);
526 }
527 }
528 #endif
04be5003 529 }
530
d437b80d 531 // Take into account transform persistence
532 aCtx->ApplyModelViewMatrix();
c827ea3a 533
f9ba5c4d 534 // remember aspects
535 const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->AspectLine();
536 const OpenGl_AspectFace* aPrevAspectFace = theWorkspace->AspectFace();
537 const OpenGl_AspectMarker* aPrevAspectMarker = theWorkspace->AspectMarker();
538 const OpenGl_AspectText* aPrevAspectText = theWorkspace->AspectText();
7d9e854b 539
540 // Apply correction for mirror transform
541 if (myIsMirrored)
542 {
c827ea3a 543 aCtx->core11fwd->glFrontFace (GL_CW);
7d9e854b 544 }
2166f0fa 545
b859a34d 546 // Collect clipping planes of structure scope
3202bf1e 547 aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes);
4269bd1b 548
1a7ece8f 549 // True if structure is fully clipped
550 bool isClipped = false;
3202bf1e 551 bool hasDisabled = false;
552 if (aCtx->Clipping().IsClippingOrCappingOn())
1a7ece8f 553 {
7c3ef2f7 554 const Graphic3d_BndBox3d& aBBox = BoundingBox();
8b1441e3 555 if (!myClipPlanes.IsNull()
556 && myClipPlanes->ToOverrideGlobal())
1a7ece8f 557 {
3202bf1e 558 aCtx->ChangeClipping().DisableGlobal (aCtx);
559 hasDisabled = aCtx->Clipping().HasDisabled();
560 }
8b1441e3 561 else if (!myTrsfPers.IsNull())
562 {
563 if (myTrsfPers->IsZoomOrRotate())
564 {
565 // Zoom/rotate persistence object lives in two worlds at the same time.
566 // Global clipping planes can not be trivially applied without being converted
567 // into local space of transformation persistence object.
568 // As more simple alternative - just clip entire object by its anchor point defined in the world space.
569 const gp_Pnt anAnchor = myTrsfPers->AnchorPoint();
570 for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More() && aPlaneIt.IsGlobal(); aPlaneIt.Next())
571 {
572 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
573 if (!aPlane->IsOn())
574 {
575 continue;
576 }
577
578 // check for clipping
579 const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
580 const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
581 if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
582 {
583 isClipped = true;
584 break;
585 }
586 }
587 }
588
589 aCtx->ChangeClipping().DisableGlobal (aCtx);
590 hasDisabled = aCtx->Clipping().HasDisabled();
591 }
1a7ece8f 592
3202bf1e 593 // Set of clipping planes that do not intersect the structure,
594 // and thus can be disabled to improve rendering performance
595 if (aBBox.IsValid()
778cd667 596 && myTrsfPers.IsNull())
3202bf1e 597 {
598 for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
1a7ece8f 599 {
3202bf1e 600 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
601 if (!aPlane->IsOn())
602 {
603 continue;
604 }
1a7ece8f 605
3202bf1e 606 // check for clipping
607 const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
608 const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(),
609 aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(),
610 aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(),
611 1.0);
612 if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space
613 {
614 isClipped = true;
615 break;
616 }
617
618 // check for no intersection (e.g. object is "entirely not clipped")
619 const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(),
620 aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(),
621 aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(),
622 1.0);
623 if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space
1a7ece8f 624 {
3202bf1e 625 aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False);
626 hasDisabled = true;
1a7ece8f 627 }
1a7ece8f 628 }
629 }
3202bf1e 630
631 if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
632 || hasDisabled)
633 {
634 // Set OCCT state uniform variables
635 aCtx->ShaderManager()->UpdateClippingState();
636 }
1a7ece8f 637 }
638
2166f0fa 639 // Render groups
cc6852f3 640 bool hasClosedPrims = false;
1a7ece8f 641 if (!isClipped)
642 {
643 renderGeometry (theWorkspace, hasClosedPrims);
644 }
2166f0fa 645
7d9e854b 646 // Reset correction for mirror transform
647 if (myIsMirrored)
c827ea3a 648 {
649 aCtx->core11fwd->glFrontFace (GL_CCW);
650 }
7d9e854b 651
b859a34d 652 // Render capping for structure groups
cc6852f3 653 if (hasClosedPrims
1a7ece8f 654 && aCtx->Clipping().IsCappingOn())
b859a34d 655 {
cc6852f3 656 OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
b859a34d 657 }
4269bd1b 658
b859a34d 659 // Revert structure clippings
3202bf1e 660 if (hasDisabled)
1a7ece8f 661 {
662 // enable planes that were previously disabled
3202bf1e 663 aCtx->ChangeClipping().RestoreDisabled (aCtx);
1a7ece8f 664 }
3202bf1e 665 aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)());
666 if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
667 || hasDisabled)
4269bd1b 668 {
30f0ad28 669 // Set OCCT state uniform variables
deb02f86 670 aCtx->ShaderManager()->RevertClippingState();
4269bd1b 671 }
672
825aa485 673 // Restore local transformation
6bd94e0d 674 aCtx->ModelWorldState.Pop();
675 aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
778cd667 676 if (!myTrsfPers.IsNull())
825aa485 677 {
825aa485 678 aCtx->WorldViewState.Pop();
825aa485 679 }
c827ea3a 680
2166f0fa 681 // Restore aspects
f9ba5c4d 682 theWorkspace->SetAspectLine (aPrevAspectLine);
683 theWorkspace->SetAspectFace (aPrevAspectFace);
684 theWorkspace->SetAspectMarker (aPrevAspectMarker);
685 theWorkspace->SetAspectText (aPrevAspectText);
2166f0fa 686
b7cd4ba7 687 // Apply highlight box
688 if (!myHighlightBox.IsNull())
689 {
f838dac4 690 theWorkspace->SetHighlightStyle (myHighlightStyle);
7d9e854b 691 myHighlightBox->Render (theWorkspace);
b7cd4ba7 692 }
693
2166f0fa 694 // Restore named status
f838dac4 695 theWorkspace->SetHighlightStyle (Handle(Graphic3d_PresentationAttributes)());
2166f0fa
SK
696}
697
5e27df78 698// =======================================================================
699// function : Release
700// purpose :
701// =======================================================================
702void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
703{
704 // Release groups
705 Clear (theGlCtx);
8e5fb5ea 706 clearHighlightBox (theGlCtx);
707 myHighlightStyle.Nullify();
5e27df78 708}
709
dd8a4ce9 710// =======================================================================
711// function : ReleaseGlResources
712// purpose :
713// =======================================================================
714void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
715{
b64d84be 716 for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
dd8a4ce9 717 {
b64d84be 718 aGroupIter.ChangeValue()->Release (theGlCtx);
dd8a4ce9 719 }
b64d84be 720 if (!myHighlightBox.IsNull())
dd8a4ce9 721 {
10b9c7df 722 myHighlightBox->Release (theGlCtx.operator->());
dd8a4ce9 723 }
724}
725
59f45b7c 726//=======================================================================
679ecdee 727//function : ShadowLink
728//purpose :
729//=======================================================================
730Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
731{
732 return new OpenGl_StructureShadow (theManager, this);
733}