1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
21 #include <OpenGl_CappingAlgo.hxx>
22 #include <OpenGl_Context.hxx>
23 #include <OpenGl_GlCore11.hxx>
24 #include <OpenGl_ShaderManager.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_Structure.hxx>
27 #include <OpenGl_telem_util.hxx>
28 #include <OpenGl_Vec.hxx>
29 #include <OpenGl_View.hxx>
30 #include <OpenGl_Workspace.hxx>
32 #include <Graphic3d_SequenceOfHClipPlane_Handle.hxx>
34 //! Auxiliary class for bounding box presentation
35 class OpenGl_BndBoxPrs : public OpenGl_Element
41 OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
43 const float Xm = theBndBox.Pmin.x;
44 const float Ym = theBndBox.Pmin.y;
45 const float Zm = theBndBox.Pmin.z;
46 const float XM = theBndBox.Pmax.x;
47 const float YM = theBndBox.Pmax.y;
48 const float ZM = theBndBox.Pmax.z;
49 myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
50 myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
51 myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
52 myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm);
53 myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm);
54 myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm);
55 myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM);
56 myVerts[7] = OpenGl_Vec3 (XM, YM, ZM);
57 myVerts[8] = OpenGl_Vec3 (XM, YM, Zm);
58 myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm);
59 myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
60 myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
61 myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
62 myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
63 myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
64 myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
67 //! Render presentation
68 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
71 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
72 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
74 glDisable (GL_LIGHTING);
75 if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
77 glDepthMask (GL_FALSE);
80 // Use highlight colors
81 glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
83 glEnableClientState (GL_VERTEX_ARRAY);
84 glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
85 glDrawArrays (GL_LINE_STRIP, 0, 16);
86 glDisableClientState (GL_VERTEX_ARRAY);
89 if (!aPrevTexture.IsNull())
91 theWorkspace->EnableTexture (aPrevTexture);
95 //! Release graphical resources
96 virtual void Release (const Handle(OpenGl_Context)& )
103 //! Protected destructor
104 virtual ~OpenGl_BndBoxPrs() {}
108 OpenGl_Vec3 myVerts[16]; //!< vertices array
112 DEFINE_STANDARD_ALLOC
116 /*----------------------------------------------------------------------*/
118 // =======================================================================
119 // function : call_util_transpose_mat
121 // =======================================================================
122 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
128 tmat[j*4+i] = mat[i][j];
131 // =======================================================================
132 // function : OpenGl_Structure
134 // =======================================================================
135 OpenGl_Structure::OpenGl_Structure ()
136 : myTransformation(NULL),
140 myAspectMarker(NULL),
142 myHighlightBox(NULL),
143 myHighlightColor(NULL),
148 myIsRaytracable = Standard_False;
149 myModificationState = 0;
153 // =======================================================================
154 // function : ~OpenGl_Structure
156 // =======================================================================
157 OpenGl_Structure::~OpenGl_Structure()
159 Release (Handle(OpenGl_Context)());
160 delete myTransformation; myTransformation = NULL;
161 delete myTransPers; myTransPers = NULL;
164 // =======================================================================
165 // function : SetTransformation
167 // =======================================================================
168 void OpenGl_Structure::SetTransformation (const float *theMatrix)
170 if (!myTransformation)
172 myTransformation = new OpenGl_Matrix();
175 matcpy (myTransformation->mat, theMatrix);
180 UpdateStateWithAncestorStructures();
185 // =======================================================================
186 // function : SetTransformPersistence
188 // =======================================================================
189 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
192 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
194 myTransPers->mode = ATransPers.Flag;
195 myTransPers->pointX = ATransPers.Point.x;
196 myTransPers->pointY = ATransPers.Point.y;
197 myTransPers->pointZ = ATransPers.Point.z;
200 // =======================================================================
201 // function : SetAspectLine
203 // =======================================================================
204 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
208 myAspectLine = new OpenGl_AspectLine();
210 myAspectLine->SetAspect (theAspect);
213 // =======================================================================
214 // function : SetAspectFace
216 // =======================================================================
217 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
221 myAspectFace = new OpenGl_AspectFace();
223 myAspectFace->SetAspect (theAspect);
228 UpdateStateWithAncestorStructures();
233 // =======================================================================
234 // function : SetAspectMarker
236 // =======================================================================
237 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
241 myAspectMarker = new OpenGl_AspectMarker();
243 myAspectMarker->SetAspect (theAspect);
246 // =======================================================================
247 // function : SetAspectText
249 // =======================================================================
250 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
254 myAspectText = new OpenGl_AspectText();
256 myAspectText->SetAspect (theAspect);
259 // =======================================================================
260 // function : SetHighlightBox
262 // =======================================================================
263 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
264 const CALL_DEF_BOUNDBOX& theBoundBox)
266 if (myHighlightBox != NULL)
268 myHighlightBox->Release (theGlCtx);
273 myHighlightBox = new OpenGl_Group();
275 myHighlightBox = new OpenGl_Group (this);
279 CALL_DEF_CONTEXTLINE aContextLine;
280 aContextLine.Color = theBoundBox.Color;
281 aContextLine.LineType = Aspect_TOL_SOLID;
282 aContextLine.Width = 1.0f;
283 myHighlightBox->SetAspectLine (aContextLine);
285 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
286 myHighlightBox->AddElement (TelParray, aBndBoxPrs);
289 // =======================================================================
290 // function : ClearHighlightBox
292 // =======================================================================
293 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
295 if (myHighlightBox != NULL)
297 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
301 // =======================================================================
302 // function : SetHighlightColor
304 // =======================================================================
305 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
306 const Standard_ShortReal R,
307 const Standard_ShortReal G,
308 const Standard_ShortReal B)
310 ClearHighlightBox (theGlCtx);
311 if (myHighlightColor == NULL)
313 myHighlightColor = new TEL_COLOUR();
316 myHighlightColor->rgb[0] = R;
317 myHighlightColor->rgb[1] = G;
318 myHighlightColor->rgb[2] = B;
319 myHighlightColor->rgb[3] = 1.F;
322 // =======================================================================
323 // function : ClearHighlightColor
325 // =======================================================================
326 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
328 ClearHighlightBox(theGlCtx);
329 delete myHighlightColor;
330 myHighlightColor = NULL;
333 // =======================================================================
334 // function : SetNamedStatus
336 // =======================================================================
337 void OpenGl_Structure::SetNamedStatus (const Standard_Integer aStatus)
339 myNamedStatus = aStatus;
344 UpdateStateWithAncestorStructures();
351 // =======================================================================
352 // function : RegisterAncestorStructure
354 // =======================================================================
355 void OpenGl_Structure::RegisterAncestorStructure (const OpenGl_Structure* theStructure) const
357 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
359 if (anIt.Value() == theStructure)
365 myAncestorStructures.Append (theStructure);
368 // =======================================================================
369 // function : UnregisterAncestorStructure
371 // =======================================================================
372 void OpenGl_Structure::UnregisterAncestorStructure (const OpenGl_Structure* theStructure) const
374 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
376 if (anIt.Value() == theStructure)
378 myAncestorStructures.Remove (anIt);
384 // =======================================================================
385 // function : UnregisterFromAncestorStructure
387 // =======================================================================
388 void OpenGl_Structure::UnregisterFromAncestorStructure() const
390 for (OpenGl_ListOfStructure::Iterator anIta (myAncestorStructures); anIta.More(); anIta.Next())
392 OpenGl_Structure* anAncestor = const_cast<OpenGl_Structure*> (anIta.ChangeValue());
394 for (OpenGl_ListOfStructure::Iterator anIts (anAncestor->myConnected); anIts.More(); anIts.Next())
396 if (anIts.Value() == this)
398 anAncestor->myConnected.Remove (anIts);
405 // =======================================================================
406 // function : UpdateStateWithAncestorStructures
408 // =======================================================================
409 void OpenGl_Structure::UpdateStateWithAncestorStructures() const
411 myModificationState++;
413 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
415 anIt.Value()->UpdateStateWithAncestorStructures();
419 // =======================================================================
420 // function : UpdateRaytracableWithAncestorStructures
422 // =======================================================================
423 void OpenGl_Structure::UpdateRaytracableWithAncestorStructures() const
425 myIsRaytracable = OpenGl_Raytrace::IsRaytracedStructure (this);
427 if (!myIsRaytracable)
429 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
431 anIt.Value()->UpdateRaytracableWithAncestorStructures();
436 // =======================================================================
437 // function : SetRaytracableWithAncestorStructures
439 // =======================================================================
440 void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
442 myIsRaytracable = Standard_True;
444 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
446 if (!anIt.Value()->IsRaytracable())
448 anIt.Value()->SetRaytracableWithAncestorStructures();
455 // =======================================================================
456 // function : Connect
458 // =======================================================================
459 void OpenGl_Structure::Connect (const OpenGl_Structure *theStructure)
461 Disconnect (theStructure);
462 myConnected.Append (theStructure);
465 if (theStructure->IsRaytracable())
467 UpdateStateWithAncestorStructures();
468 SetRaytracableWithAncestorStructures();
471 theStructure->RegisterAncestorStructure (this);
475 // =======================================================================
476 // function : Disconnect
478 // =======================================================================
479 void OpenGl_Structure::Disconnect (const OpenGl_Structure *theStructure)
481 OpenGl_ListOfStructure::Iterator its (myConnected);
484 // Check for the given structure
485 if (its.Value() == theStructure)
487 myConnected.Remove (its);
490 if (theStructure->IsRaytracable())
492 UpdateStateWithAncestorStructures();
493 UpdateRaytracableWithAncestorStructures();
496 theStructure->UnregisterAncestorStructure (this);
505 // =======================================================================
506 // function : AddGroup
508 // =======================================================================
509 OpenGl_Group * OpenGl_Structure::AddGroup()
513 OpenGl_Group *g = new OpenGl_Group();
515 OpenGl_Group *g = new OpenGl_Group (this);
522 // =======================================================================
523 // function : RemoveGroup
525 // =======================================================================
526 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
527 const OpenGl_Group* theGroup)
529 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
531 // Check for the given group
532 if (anIter.Value() == theGroup)
534 myGroups.Remove (anIter);
537 if (theGroup->IsRaytracable())
539 UpdateStateWithAncestorStructures();
540 UpdateRaytracableWithAncestorStructures();
545 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (theGroup));
551 // =======================================================================
554 // =======================================================================
555 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
558 Standard_Boolean aRaytracableGroupDeleted (Standard_False);
562 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
565 aRaytracableGroupDeleted |= anIter.Value()->IsRaytracable();
569 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
574 if (aRaytracableGroupDeleted)
576 UpdateStateWithAncestorStructures();
577 UpdateRaytracableWithAncestorStructures();
582 // =======================================================================
585 // =======================================================================
586 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
588 // Process the structure only if visible
589 if ( myNamedStatus & OPENGL_NS_HIDE )
592 // Render named status
593 const Standard_Integer named_status = AWorkspace->NamedStatus;
594 AWorkspace->NamedStatus |= myNamedStatus;
596 // Is rendering in ADD or IMMEDIATE mode?
597 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
599 const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
601 // Apply local transformation
602 GLint matrix_mode = 0;
603 const OpenGl_Matrix *local_trsf = NULL;
604 if (myTransformation)
608 Tmatrix3 aModelWorld;
609 call_util_transpose_mat (*aModelWorld, myTransformation->mat);
610 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
612 if (!aCtx->ShaderManager()->IsEmpty())
615 glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
617 Tmatrix3 aProjection;
618 glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
620 aCtx->ShaderManager()->UpdateModelWorldStateTo (aModelWorld);
621 aCtx->ShaderManager()->UpdateWorldViewStateTo (aWorldView);
622 aCtx->ShaderManager()->UpdateProjectionStateTo (aProjection);
625 glMatrixMode (GL_MODELVIEW);
627 glScalef (1.F, 1.F, 1.F);
628 glMultMatrixf (*aModelWorld);
632 glMatrixMode (GL_MODELVIEW);
635 local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
639 // Apply transform persistence
640 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
641 if ( myTransPers && myTransPers->mode != 0 )
643 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
647 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
648 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
649 const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
650 const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
652 AWorkspace->SetAspectLine(myAspectLine);
654 AWorkspace->SetAspectFace(myAspectFace);
656 AWorkspace->SetAspectMarker(myAspectMarker);
658 AWorkspace->SetAspectText(myAspectText);
660 // Apply highlight box
662 myHighlightBox->Render( AWorkspace );
664 // Apply highlight color
665 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
666 if (myHighlightColor)
667 AWorkspace->HighlightColor = myHighlightColor;
669 // Render connected structures
670 OpenGl_ListOfStructure::Iterator its(myConnected);
673 its.Value()->Render(AWorkspace);
677 // Set up plane equations for non-structure transformed global model-view matrix
678 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
680 // List of planes to be applied to context state
681 Handle(Graphic3d_SequenceOfHClipPlane) aUserPlanes;
683 // Collect clipping planes of structure scope
684 if (!myClipPlanes.IsEmpty())
686 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
687 for (; aClippingIt.More(); aClippingIt.Next())
689 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
690 if (!aClipPlane->IsOn())
695 if (aUserPlanes.IsNull())
697 aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
700 aUserPlanes->Append (aClipPlane);
704 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
706 // add planes at loaded view matrix state
707 aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
709 // Set OCCT state uniform variables
710 if (!aContext->ShaderManager()->IsEmpty())
712 aContext->ShaderManager()->UpdateClippingState();
717 OpenGl_ListOfGroup::Iterator itg(myGroups);
720 itg.Value()->Render(AWorkspace);
724 // Render capping for structure groups
725 if (!aContext->Clipping().Planes().IsEmpty())
727 OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
730 // Revert structure clippings
731 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
733 aContext->ChangeClipping().Remove (*aUserPlanes);
735 // Set OCCT state uniform variables
736 if (!aContext->ShaderManager()->IsEmpty())
738 aContext->ShaderManager()->RevertClippingState();
742 // Restore highlight color
743 AWorkspace->HighlightColor = highlight_color;
746 AWorkspace->SetAspectLine(aspect_line);
747 AWorkspace->SetAspectFace(aspect_face);
748 AWorkspace->SetAspectMarker(aspect_marker);
749 AWorkspace->SetAspectText(aspect_text);
751 // Restore transform persistence
752 if ( myTransPers && myTransPers->mode != 0 )
754 AWorkspace->ActiveView()->BeginTransformPersistence (aContext, trans_pers);
757 // Restore local transformation
758 if (myTransformation)
763 glMatrixMode (matrix_mode);
765 Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
766 { 0.f, 1.f, 0.f, 0.f },
767 { 0.f, 0.f, 1.f, 0.f },
768 { 0.f, 0.f, 0.f, 1.f } };
770 aContext->ShaderManager()->RevertModelWorldStateTo (aModelWorldState);
774 AWorkspace->SetStructureMatrix (local_trsf, true);
776 glMatrixMode (GL_MODELVIEW);
781 // Restore named status
782 AWorkspace->NamedStatus = named_status;
785 // =======================================================================
786 // function : Release
788 // =======================================================================
789 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
793 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
794 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
795 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
796 OpenGl_Element::Destroy (theGlCtx, myAspectText);
797 ClearHighlightColor (theGlCtx);
800 // Remove from connected list of ancestor
801 UnregisterFromAncestorStructure();
805 // =======================================================================
806 // function : ReleaseGlResources
808 // =======================================================================
809 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
811 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
813 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
816 aGroup->Release (theGlCtx);
819 if (myAspectLine != NULL)
821 myAspectLine->Release (theGlCtx);
823 if (myAspectFace != NULL)
825 myAspectFace->Release (theGlCtx);
827 if (myAspectMarker != NULL)
829 myAspectMarker->Release (theGlCtx);
831 if (myAspectText != NULL)
833 myAspectText->Release (theGlCtx);
835 if (myHighlightBox != NULL)
837 myHighlightBox->Release (theGlCtx);
841 //=======================================================================
842 //function : SetZLayer
844 //=======================================================================
845 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
847 myZLayer = theLayerIndex;
850 //=======================================================================
851 //function : GetZLayer
853 //=======================================================================
854 Standard_Integer OpenGl_Structure::GetZLayer () const