0024070: OpenGL capped object-level clipping planes
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
index 8ef32fc..16a9ff9 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #include <OpenGl_GlCore11.hxx>
 
 #include <OpenGl_Structure.hxx>
 
-#include <OpenGl_Polyline.hxx>
 #include <OpenGl_Workspace.hxx>
+#include <OpenGl_Vec.hxx>
 #include <OpenGl_View.hxx>
-
+#include <OpenGl_CappingAlgo.hxx>
+#include <OpenGl_Context.hxx>
 #include <OpenGl_telem_util.hxx>
 
+//! Auxiliary class for bounding box presentation
+class OpenGl_BndBoxPrs : public OpenGl_Element
+{
+
+public:
+
+  //! Main constructor
+  OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
+  {
+    const float Xm = theBndBox.Pmin.x;
+    const float Ym = theBndBox.Pmin.y;
+    const float Zm = theBndBox.Pmin.z;
+    const float XM = theBndBox.Pmax.x;
+    const float YM = theBndBox.Pmax.y;
+    const float ZM = theBndBox.Pmax.z;
+    myVerts[0]  = OpenGl_Vec3 (Xm, Ym, Zm);
+    myVerts[1]  = OpenGl_Vec3 (Xm, Ym, ZM);
+    myVerts[2]  = OpenGl_Vec3 (Xm, YM, ZM);
+    myVerts[3]  = OpenGl_Vec3 (Xm, YM, Zm);
+    myVerts[4]  = OpenGl_Vec3 (Xm, Ym, Zm);
+    myVerts[5]  = OpenGl_Vec3 (XM, Ym, Zm);
+    myVerts[6]  = OpenGl_Vec3 (XM, Ym, ZM);
+    myVerts[7]  = OpenGl_Vec3 (XM, YM, ZM);
+    myVerts[8]  = OpenGl_Vec3 (XM, YM, Zm);
+    myVerts[9]  = OpenGl_Vec3 (XM, Ym, Zm);
+    myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
+    myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
+    myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
+    myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
+    myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
+    myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
+  }
+
+  //! Render presentation
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const
+  {
+    // Apply line aspect
+    const OpenGl_AspectLine*     anAspectLine = theWorkspace->AspectLine (Standard_True);
+    const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
+
+    glDisable (GL_LIGHTING);
+    if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
+    {
+      glDepthMask (GL_FALSE);
+    }
+
+    // Use highlight colors
+    glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
+
+    glEnableClientState (GL_VERTEX_ARRAY);
+    glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
+    glDrawArrays (GL_LINE_STRIP, 0, 16);
+    glDisableClientState (GL_VERTEX_ARRAY);
+
+    // restore aspects
+    if (!aPrevTexture.IsNull())
+    {
+      theWorkspace->EnableTexture (aPrevTexture);
+    }
+  }
+
+  //! Release graphical resources
+  virtual void Release (const Handle(OpenGl_Context)& )
+  {
+    //
+  }
+
+protected:
+
+  //! Protected destructor
+  virtual ~OpenGl_BndBoxPrs() {}
+
+private:
+
+  OpenGl_Vec3 myVerts[16]; //!< vertices array
+
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+};
 
 /*----------------------------------------------------------------------*/
 
+// =======================================================================
+// function : call_util_transpose_mat
+// purpose  :
+// =======================================================================
 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
 {
   int i, j;
@@ -40,8 +125,10 @@ static void call_util_transpose_mat (float tmat[16], float mat[4][4])
       tmat[j*4+i] = mat[i][j];
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : OpenGl_Structure
+// purpose  :
+// =======================================================================
 OpenGl_Structure::OpenGl_Structure ()
 : myTransformation(NULL),
   myTransPers(NULL),
@@ -56,8 +143,10 @@ OpenGl_Structure::OpenGl_Structure ()
 {
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ~OpenGl_Structure
+// purpose  :
+// =======================================================================
 OpenGl_Structure::~OpenGl_Structure()
 {
   Release (Handle(OpenGl_Context)());
@@ -65,8 +154,10 @@ OpenGl_Structure::~OpenGl_Structure()
   delete myTransPers;       myTransPers       = NULL;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetTransformation
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetTransformation(const float *AMatrix)
 {
   if (!myTransformation)
@@ -75,8 +166,10 @@ void OpenGl_Structure::SetTransformation(const float *AMatrix)
   matcpy( myTransformation->mat, AMatrix );
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetTransformPersistence
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
 {
   if (!myTransPers)
@@ -88,8 +181,10 @@ void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTE
   myTransPers->pointZ = ATransPers.Point.z;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectLine
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
 {
   if (!myAspectLine)
@@ -97,8 +192,10 @@ void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
   myAspectLine->SetContext( AContext );
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectFace
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
                                       const CALL_DEF_CONTEXTFILLAREA& theAspect)
 {
@@ -109,17 +206,24 @@ void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
   myAspectFace->Init (theCtx, theAspect);
 }
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
+// =======================================================================
+// function : SetAspectMarker
+// purpose  :
+// =======================================================================
+void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
+                                        const CALL_DEF_CONTEXTMARKER& theAspect)
 {
   if (!myAspectMarker)
+  {
     myAspectMarker = new OpenGl_AspectMarker();
-  myAspectMarker->SetContext( AContext );
+  }
+  myAspectMarker->Init (theCtx, theAspect);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectText
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
 {
   if (!myAspectText)
@@ -127,8 +231,10 @@ void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
   myAspectText->SetContext( AContext );
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetHighlightBox
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
                                         const CALL_DEF_BOUNDBOX&      theBoundBox)
 {
@@ -147,38 +253,14 @@ void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
   aContextLine.Width    = 1.0f;
   myHighlightBox->SetAspectLine (aContextLine);
 
-#define CALL_MAX_BOUNDBOXSIZE 16
-
-  Graphic3d_Array1OfVertex aPoints (1, CALL_MAX_BOUNDBOXSIZE);
-  const float Xm = theBoundBox.Pmin.x;
-  const float Ym = theBoundBox.Pmin.y;
-  const float Zm = theBoundBox.Pmin.z;
-  const float XM = theBoundBox.Pmax.x;
-  const float YM = theBoundBox.Pmax.y;
-  const float ZM = theBoundBox.Pmax.z;
-  aPoints( 1).SetCoord (Xm, Ym, Zm);
-  aPoints( 2).SetCoord (Xm, Ym, ZM);
-  aPoints( 3).SetCoord (Xm, YM, ZM);
-  aPoints( 4).SetCoord (Xm, YM, Zm);
-  aPoints( 5).SetCoord (Xm, Ym, Zm);
-  aPoints( 6).SetCoord (XM, Ym, Zm);
-  aPoints( 7).SetCoord (XM, Ym, ZM);
-  aPoints( 8).SetCoord (XM, YM, ZM);
-  aPoints( 9).SetCoord (XM, YM, Zm);
-  aPoints(10).SetCoord (XM, Ym, Zm);
-  aPoints(11).SetCoord (XM, YM, Zm);
-  aPoints(12).SetCoord (Xm, YM, Zm);
-  aPoints(13).SetCoord (Xm, YM, ZM);
-  aPoints(14).SetCoord (XM, YM, ZM);
-  aPoints(15).SetCoord (XM, Ym, ZM);
-  aPoints(16).SetCoord (Xm, Ym, ZM);
-
-  OpenGl_Polyline* aPolyline = new OpenGl_Polyline (aPoints);
-  myHighlightBox->AddElement (TelPolyline, aPolyline);
+  OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
+  myHighlightBox->AddElement (TelParray, aBndBoxPrs);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ClearHighlightBox
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
 {
   if (myHighlightBox != NULL)
@@ -187,8 +269,10 @@ void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetHighlightColor
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
                                           const Standard_ShortReal R,
                                           const Standard_ShortReal G,
@@ -206,8 +290,10 @@ void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx
   myHighlightColor->rgb[3] = 1.F;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ClearHighlightColor
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
 {
   ClearHighlightBox(theGlCtx);
@@ -215,16 +301,20 @@ void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlC
   myHighlightColor = NULL;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Connect
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
 {
   Disconnect (AStructure);
   myConnected.Append(AStructure);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Disconnect
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
 {
   OpenGl_ListOfStructure::Iterator its(myConnected);
@@ -240,8 +330,10 @@ void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : AddGroup
+// purpose  :
+// =======================================================================
 OpenGl_Group * OpenGl_Structure::AddGroup ()
 {
   // Create new group
@@ -250,8 +342,10 @@ OpenGl_Group * OpenGl_Structure::AddGroup ()
   return g;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : RemoveGroup
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
                                     const OpenGl_Group*           theGroup)
 {
@@ -268,8 +362,10 @@ void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
 {
   // Release groups
@@ -281,8 +377,10 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
   myGroups.Clear();
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
 {
   // Process the structure only if visible
@@ -358,6 +456,25 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
     its.Next();
   }
 
+  // Set up plane equations for non-structure transformed global model-view matrix
+  const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
+
+  // Collect planes which should be turned on for structure
+  Graphic3d_SetOfHClipPlane aPlanesOn;
+  Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
+  for (; aPlaneIt.More(); aPlaneIt.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value();
+    if (aUserPln->IsOn())
+      aPlanesOn.Add (aUserPln);
+  }
+
+  // set structure clipping planes
+  if (aPlanesOn.Size() > 0)
+  {
+    aContext->ChangeClipping().Set (aPlanesOn, AWorkspace->ViewMatrix());
+  }
+
   // Render groups
   OpenGl_ListOfGroup::Iterator itg(myGroups);
   while (itg.More())
@@ -366,6 +483,15 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
     itg.Next();
   }
 
+  // Render cappings for structure groups
+  OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
+
+  // unset structure clipping planes
+  if (aPlanesOn.Size() > 0)
+  {
+    aContext->ChangeClipping().Unset (aPlanesOn);
+  }
+
   // Restore highlight color
   AWorkspace->HighlightColor = highlight_color;
 
@@ -457,7 +583,6 @@ void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCt
 //function : SetZLayer
 //purpose  :
 //=======================================================================
-
 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
 {
   myZLayer = theLayerIndex;
@@ -467,7 +592,6 @@ void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
 //function : GetZLayer
 //purpose  :
 //=======================================================================
-
 Standard_Integer OpenGl_Structure::GetZLayer () const
 {
   return myZLayer;