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