1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
25 #include <OpenGl_CappingAlgo.hxx>
26 #include <OpenGl_Context.hxx>
27 #include <OpenGl_GlCore11.hxx>
28 #include <OpenGl_ShaderManager.hxx>
29 #include <OpenGl_ShaderProgram.hxx>
30 #include <OpenGl_Structure.hxx>
31 #include <OpenGl_telem_util.hxx>
32 #include <OpenGl_Vec.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Workspace.hxx>
36 #include <Graphic3d_SetOfHClipPlane_Handle.hxx>
38 //! Auxiliary class for bounding box presentation
39 class OpenGl_BndBoxPrs : public OpenGl_Element
45 OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
47 const float Xm = theBndBox.Pmin.x;
48 const float Ym = theBndBox.Pmin.y;
49 const float Zm = theBndBox.Pmin.z;
50 const float XM = theBndBox.Pmax.x;
51 const float YM = theBndBox.Pmax.y;
52 const float ZM = theBndBox.Pmax.z;
53 myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
54 myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
55 myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
56 myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm);
57 myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm);
58 myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm);
59 myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM);
60 myVerts[7] = OpenGl_Vec3 (XM, YM, ZM);
61 myVerts[8] = OpenGl_Vec3 (XM, YM, Zm);
62 myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm);
63 myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
64 myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
65 myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
66 myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
67 myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
68 myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
71 //! Render presentation
72 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
75 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
76 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
78 glDisable (GL_LIGHTING);
79 if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
81 glDepthMask (GL_FALSE);
84 // Use highlight colors
85 glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
87 glEnableClientState (GL_VERTEX_ARRAY);
88 glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
89 glDrawArrays (GL_LINE_STRIP, 0, 16);
90 glDisableClientState (GL_VERTEX_ARRAY);
93 if (!aPrevTexture.IsNull())
95 theWorkspace->EnableTexture (aPrevTexture);
99 //! Release graphical resources
100 virtual void Release (const Handle(OpenGl_Context)& )
107 //! Protected destructor
108 virtual ~OpenGl_BndBoxPrs() {}
112 OpenGl_Vec3 myVerts[16]; //!< vertices array
116 DEFINE_STANDARD_ALLOC
120 /*----------------------------------------------------------------------*/
122 // =======================================================================
123 // function : call_util_transpose_mat
125 // =======================================================================
126 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
132 tmat[j*4+i] = mat[i][j];
135 // =======================================================================
136 // function : OpenGl_Structure
138 // =======================================================================
139 OpenGl_Structure::OpenGl_Structure ()
140 : myTransformation(NULL),
144 myAspectMarker(NULL),
146 myHighlightBox(NULL),
147 myHighlightColor(NULL),
152 myIsRaytracable = Standard_False;
153 myModificationState = 0;
157 // =======================================================================
158 // function : ~OpenGl_Structure
160 // =======================================================================
161 OpenGl_Structure::~OpenGl_Structure()
163 Release (Handle(OpenGl_Context)());
164 delete myTransformation; myTransformation = NULL;
165 delete myTransPers; myTransPers = NULL;
168 // =======================================================================
169 // function : SetTransformation
171 // =======================================================================
172 void OpenGl_Structure::SetTransformation (const float *theMatrix)
174 if (!myTransformation)
176 myTransformation = new OpenGl_Matrix();
179 matcpy (myTransformation->mat, theMatrix);
184 UpdateStateWithAncestorStructures();
189 // =======================================================================
190 // function : SetTransformPersistence
192 // =======================================================================
193 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
196 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
198 myTransPers->mode = ATransPers.Flag;
199 myTransPers->pointX = ATransPers.Point.x;
200 myTransPers->pointY = ATransPers.Point.y;
201 myTransPers->pointZ = ATransPers.Point.z;
204 // =======================================================================
205 // function : SetAspectLine
207 // =======================================================================
208 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
212 myAspectLine = new OpenGl_AspectLine();
214 myAspectLine->SetAspect (theAspect);
217 // =======================================================================
218 // function : SetAspectFace
220 // =======================================================================
221 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
225 myAspectFace = new OpenGl_AspectFace();
227 myAspectFace->SetAspect (theAspect);
232 UpdateStateWithAncestorStructures();
237 // =======================================================================
238 // function : SetAspectMarker
240 // =======================================================================
241 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
245 myAspectMarker = new OpenGl_AspectMarker();
247 myAspectMarker->SetAspect (theAspect);
250 // =======================================================================
251 // function : SetAspectText
253 // =======================================================================
254 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
258 myAspectText = new OpenGl_AspectText();
260 myAspectText->SetAspect (theAspect);
263 // =======================================================================
264 // function : SetHighlightBox
266 // =======================================================================
267 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
268 const CALL_DEF_BOUNDBOX& theBoundBox)
270 if (myHighlightBox != NULL)
272 myHighlightBox->Release (theGlCtx);
277 myHighlightBox = new OpenGl_Group();
279 myHighlightBox = new OpenGl_Group (this);
283 CALL_DEF_CONTEXTLINE aContextLine;
284 aContextLine.Color = theBoundBox.Color;
285 aContextLine.LineType = Aspect_TOL_SOLID;
286 aContextLine.Width = 1.0f;
287 myHighlightBox->SetAspectLine (aContextLine);
289 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
290 myHighlightBox->AddElement (TelParray, aBndBoxPrs);
293 // =======================================================================
294 // function : ClearHighlightBox
296 // =======================================================================
297 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
299 if (myHighlightBox != NULL)
301 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
305 // =======================================================================
306 // function : SetHighlightColor
308 // =======================================================================
309 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
310 const Standard_ShortReal R,
311 const Standard_ShortReal G,
312 const Standard_ShortReal B)
314 ClearHighlightBox (theGlCtx);
315 if (myHighlightColor == NULL)
317 myHighlightColor = new TEL_COLOUR();
320 myHighlightColor->rgb[0] = R;
321 myHighlightColor->rgb[1] = G;
322 myHighlightColor->rgb[2] = B;
323 myHighlightColor->rgb[3] = 1.F;
326 // =======================================================================
327 // function : ClearHighlightColor
329 // =======================================================================
330 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
332 ClearHighlightBox(theGlCtx);
333 delete myHighlightColor;
334 myHighlightColor = NULL;
337 // =======================================================================
338 // function : SetNamedStatus
340 // =======================================================================
341 void OpenGl_Structure::SetNamedStatus (const Standard_Integer aStatus)
343 myNamedStatus = aStatus;
348 UpdateStateWithAncestorStructures();
355 // =======================================================================
356 // function : RegisterAncestorStructure
358 // =======================================================================
359 void OpenGl_Structure::RegisterAncestorStructure (const OpenGl_Structure* theStructure) const
361 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
363 if (anIt.Value() == theStructure)
369 myAncestorStructures.Append (theStructure);
372 // =======================================================================
373 // function : UnregisterAncestorStructure
375 // =======================================================================
376 void OpenGl_Structure::UnregisterAncestorStructure (const OpenGl_Structure* theStructure) const
378 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
380 if (anIt.Value() == theStructure)
382 myAncestorStructures.Remove (anIt);
388 // =======================================================================
389 // function : UpdateStateWithAncestorStructures
391 // =======================================================================
392 void OpenGl_Structure::UpdateStateWithAncestorStructures() const
394 myModificationState++;
396 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
398 anIt.Value()->UpdateStateWithAncestorStructures();
402 // =======================================================================
403 // function : UpdateRaytracableWithAncestorStructures
405 // =======================================================================
406 void OpenGl_Structure::UpdateRaytracableWithAncestorStructures() const
408 myIsRaytracable = OpenGl_Raytrace::IsRaytracedStructure (this);
410 if (!myIsRaytracable)
412 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
414 anIt.Value()->UpdateRaytracableWithAncestorStructures();
419 // =======================================================================
420 // function : SetRaytracableWithAncestorStructures
422 // =======================================================================
423 void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
425 myIsRaytracable = Standard_True;
427 for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
429 if (!anIt.Value()->IsRaytracable())
431 anIt.Value()->SetRaytracableWithAncestorStructures();
438 // =======================================================================
439 // function : Connect
441 // =======================================================================
442 void OpenGl_Structure::Connect (const OpenGl_Structure *theStructure)
444 Disconnect (theStructure);
445 myConnected.Append (theStructure);
448 if (theStructure->IsRaytracable())
450 UpdateStateWithAncestorStructures();
451 SetRaytracableWithAncestorStructures();
454 theStructure->RegisterAncestorStructure (this);
458 // =======================================================================
459 // function : Disconnect
461 // =======================================================================
462 void OpenGl_Structure::Disconnect (const OpenGl_Structure *theStructure)
464 OpenGl_ListOfStructure::Iterator its (myConnected);
467 // Check for the given structure
468 if (its.Value() == theStructure)
470 myConnected.Remove (its);
473 if (theStructure->IsRaytracable())
475 UpdateStateWithAncestorStructures();
476 UpdateRaytracableWithAncestorStructures();
479 theStructure->UnregisterAncestorStructure (this);
488 // =======================================================================
489 // function : AddGroup
491 // =======================================================================
492 OpenGl_Group * OpenGl_Structure::AddGroup()
496 OpenGl_Group *g = new OpenGl_Group();
498 OpenGl_Group *g = new OpenGl_Group (this);
505 // =======================================================================
506 // function : RemoveGroup
508 // =======================================================================
509 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
510 const OpenGl_Group* theGroup)
512 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
514 // Check for the given group
515 if (anIter.Value() == theGroup)
517 myGroups.Remove (anIter);
520 if (theGroup->IsRaytracable())
522 UpdateStateWithAncestorStructures();
523 UpdateRaytracableWithAncestorStructures();
528 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (theGroup));
534 // =======================================================================
537 // =======================================================================
538 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
541 Standard_Boolean aRaytracableGroupDeleted (Standard_False);
545 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
548 aRaytracableGroupDeleted |= anIter.Value()->IsRaytracable();
552 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
557 if (aRaytracableGroupDeleted)
559 UpdateStateWithAncestorStructures();
560 UpdateRaytracableWithAncestorStructures();
565 // =======================================================================
568 // =======================================================================
569 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
571 // Process the structure only if visible
572 if ( myNamedStatus & OPENGL_NS_HIDE )
575 // Render named status
576 const Standard_Integer named_status = AWorkspace->NamedStatus;
577 AWorkspace->NamedStatus |= myNamedStatus;
579 // Is rendering in ADD or IMMEDIATE mode?
580 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
582 const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
584 // Apply local transformation
585 GLint matrix_mode = 0;
586 const OpenGl_Matrix *local_trsf = NULL;
587 if (myTransformation)
591 Tmatrix3 aModelWorld;
592 call_util_transpose_mat (*aModelWorld, myTransformation->mat);
593 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
595 if (!aCtx->ShaderManager()->IsEmpty())
598 glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
600 Tmatrix3 aProjection;
601 glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
603 aCtx->ShaderManager()->UpdateModelWorldStateTo (aModelWorld);
604 aCtx->ShaderManager()->UpdateWorldViewStateTo (aWorldView);
605 aCtx->ShaderManager()->UpdateProjectionStateTo (aProjection);
608 glMatrixMode (GL_MODELVIEW);
610 glScalef (1.F, 1.F, 1.F);
611 glMultMatrixf (*aModelWorld);
615 glMatrixMode (GL_MODELVIEW);
618 local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
622 // Apply transform persistence
623 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
624 if ( myTransPers && myTransPers->mode != 0 )
626 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
630 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
631 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
632 const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
633 const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
635 AWorkspace->SetAspectLine(myAspectLine);
637 AWorkspace->SetAspectFace(myAspectFace);
639 AWorkspace->SetAspectMarker(myAspectMarker);
641 AWorkspace->SetAspectText(myAspectText);
643 // Apply highlight box
645 myHighlightBox->Render( AWorkspace );
647 // Apply highlight color
648 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
649 if (myHighlightColor)
650 AWorkspace->HighlightColor = myHighlightColor;
652 // Render connected structures
653 OpenGl_ListOfStructure::Iterator its(myConnected);
656 its.Value()->Render(AWorkspace);
660 // Set up plane equations for non-structure transformed global model-view matrix
661 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
663 // List of planes to be applied to context state
664 Handle(Graphic3d_SetOfHClipPlane) aUserPlanes;
666 // Collect clipping planes of structure scope
667 if (!myClipPlanes.IsEmpty())
669 Graphic3d_SetOfHClipPlane::Iterator aClippingIt (myClipPlanes);
670 for (; aClippingIt.More(); aClippingIt.Next())
672 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
673 if (!aClipPlane->IsOn())
678 if (aUserPlanes.IsNull())
680 aUserPlanes = new Graphic3d_SetOfHClipPlane();
683 aUserPlanes->Add (aClipPlane);
687 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
689 // add planes at loaded view matrix state
690 aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
692 // Set OCCT state uniform variables
693 if (!aContext->ShaderManager()->IsEmpty())
695 aContext->ShaderManager()->UpdateClippingState();
700 OpenGl_ListOfGroup::Iterator itg(myGroups);
703 itg.Value()->Render(AWorkspace);
707 // Render capping for structure groups
708 if (!aContext->Clipping().Planes().IsEmpty())
710 OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
713 // Revert structure clippings
714 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
716 aContext->ChangeClipping().Remove (*aUserPlanes);
718 // Set OCCT state uniform variables
719 if (!aContext->ShaderManager()->IsEmpty())
721 aContext->ShaderManager()->RevertClippingState();
725 // Restore highlight color
726 AWorkspace->HighlightColor = highlight_color;
729 AWorkspace->SetAspectLine(aspect_line);
730 AWorkspace->SetAspectFace(aspect_face);
731 AWorkspace->SetAspectMarker(aspect_marker);
732 AWorkspace->SetAspectText(aspect_text);
734 // Restore transform persistence
735 if ( myTransPers && myTransPers->mode != 0 )
737 AWorkspace->ActiveView()->BeginTransformPersistence (aContext, trans_pers);
740 // Restore local transformation
741 if (myTransformation)
746 glMatrixMode (matrix_mode);
748 Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
749 { 0.f, 1.f, 0.f, 0.f },
750 { 0.f, 0.f, 1.f, 0.f },
751 { 0.f, 0.f, 0.f, 1.f } };
753 aContext->ShaderManager()->RevertModelWorldStateTo (aModelWorldState);
757 AWorkspace->SetStructureMatrix (local_trsf, true);
759 glMatrixMode (GL_MODELVIEW);
764 // Restore named status
765 AWorkspace->NamedStatus = named_status;
768 // =======================================================================
769 // function : Release
771 // =======================================================================
772 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
776 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
777 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
778 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
779 OpenGl_Element::Destroy (theGlCtx, myAspectText);
780 ClearHighlightColor (theGlCtx);
783 // =======================================================================
784 // function : ReleaseGlResources
786 // =======================================================================
787 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
789 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
791 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
794 aGroup->Release (theGlCtx);
797 if (myAspectLine != NULL)
799 myAspectLine->Release (theGlCtx);
801 if (myAspectFace != NULL)
803 myAspectFace->Release (theGlCtx);
805 if (myAspectMarker != NULL)
807 myAspectMarker->Release (theGlCtx);
809 if (myAspectText != NULL)
811 myAspectText->Release (theGlCtx);
813 if (myHighlightBox != NULL)
815 myHighlightBox->Release (theGlCtx);
819 //=======================================================================
820 //function : SetZLayer
822 //=======================================================================
823 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
825 myZLayer = theLayerIndex;
828 //=======================================================================
829 //function : GetZLayer
831 //=======================================================================
832 Standard_Integer OpenGl_Structure::GetZLayer () const