0026122: Visualization, TKOpenGl - clipping and capping is broken when ffp is disable...
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
index 26bea9d..69d2e4d 100644 (file)
@@ -27,8 +27,6 @@
 
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
 
-IMPLEMENT_STANDARD_HANDLE (OpenGl_Structure, Graphic3d_CStructure)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure, Graphic3d_CStructure)
 
 //! Auxiliary class for bounding box presentation
 class OpenGl_BndBoxPrs : public OpenGl_Element
@@ -119,17 +117,17 @@ public:
 // =======================================================================
 OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
 : Graphic3d_CStructure (theManager),
-  myTransformation(NULL),
-  myTransPers(NULL),
-  myAspectLine(NULL),
-  myAspectFace(NULL),
-  myAspectMarker(NULL),
-  myAspectText(NULL),
-  myHighlightColor(NULL),
-  myIsRaytracable (Standard_False),
-  myModificationState (0),
-  myIsCulled (Standard_True),
-  myIsMirrored (Standard_False)
+  myTransformation     (NULL),
+  myAspectLine         (NULL),
+  myAspectFace         (NULL),
+  myAspectMarker       (NULL),
+  myAspectText         (NULL),
+  myHighlightColor     (NULL),
+  myInstancedStructure (NULL),
+  myIsRaytracable      (Standard_False),
+  myModificationState  (0),
+  myIsCulled           (Standard_True),
+  myIsMirrored         (Standard_False)
 {
   //
 }
@@ -142,7 +140,6 @@ OpenGl_Structure::~OpenGl_Structure()
 {
   Release (Handle(OpenGl_Context)());
   delete myTransformation;  myTransformation  = NULL;
-  delete myTransPers;       myTransPers       = NULL;
 }
 
 // =======================================================================
@@ -151,8 +148,6 @@ OpenGl_Structure::~OpenGl_Structure()
 // =======================================================================
 void OpenGl_Structure::UpdateAspects()
 {
-  SetTransformPersistence (TransformPersistence);
-
   if (ContextLine.IsDef)
     SetAspectLine (ContextLine);
 
@@ -189,28 +184,12 @@ void OpenGl_Structure::UpdateTransformation()
 
   matcpy (myTransformation->mat, &Graphic3d_CStructure::Transformation[0][0]);
 
-  if (myIsRaytracable)
+  if (IsRaytracable())
   {
-    UpdateStateWithAncestorStructures();
+    ++myModificationState;
   }
 }
 
-// =======================================================================
-// function : SetTransformPersistence
-// purpose  :
-// =======================================================================
-void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
-{
-  if (!myTransPers)
-    myTransPers = new TEL_TRANSFORM_PERSISTENCE;
-
-  myTransPers->mode = ATransPers.Flag;
-  myTransPers->pointX = ATransPers.Point.x;
-  myTransPers->pointY = ATransPers.Point.y;
-  myTransPers->pointZ = ATransPers.Point.z;
-  MarkAsNotCulled();
-}
-
 // =======================================================================
 // function : SetAspectLine
 // purpose  :
@@ -236,9 +215,9 @@ void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
   }
   myAspectFace->SetAspect (theAspect);
 
-  if (myIsRaytracable)
+  if (IsRaytracable())
   {
-    UpdateStateWithAncestorStructures();
+    ++myModificationState;
   }
 }
 
@@ -365,111 +344,41 @@ void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlC
 // =======================================================================
 void OpenGl_Structure::OnVisibilityChanged()
 {
-  if (myIsRaytracable)
+  if (IsRaytracable())
   {
-    UpdateStateWithAncestorStructures();
+    ++myModificationState;
   }
 }
 
 // =======================================================================
-// function : RegisterAncestorStructure
+// function : IsRaytracable
 // purpose  :
 // =======================================================================
-void OpenGl_Structure::RegisterAncestorStructure (const OpenGl_Structure* theStructure) const
+Standard_Boolean OpenGl_Structure::IsRaytracable() const
 {
-  for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
+  if (!myGroups.IsEmpty())
   {
-    if (anIt.Value() == theStructure)
-    {
-      return;
-    }
+    return myIsRaytracable; // geometry structure
   }
-
-  myAncestorStructures.Append (theStructure);
-}
-
-// =======================================================================
-// function : UnregisterAncestorStructure
-// purpose  :
-// =======================================================================
-void OpenGl_Structure::UnregisterAncestorStructure (const OpenGl_Structure* theStructure) const
-{
-  for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
-  {
-    if (anIt.Value() == theStructure)
-    {
-      myAncestorStructures.Remove (anIt);
-      return;
-    }
-  }
-}
-
-// =======================================================================
-// function : UnregisterFromAncestorStructure
-// purpose  :
-// =======================================================================
-void OpenGl_Structure::UnregisterFromAncestorStructure() const
-{
-  for (OpenGl_ListOfStructure::Iterator anIta (myAncestorStructures); anIta.More(); anIta.Next())
-  {
-    OpenGl_Structure* anAncestor = const_cast<OpenGl_Structure*> (anIta.ChangeValue());
-
-    for (OpenGl_ListOfStructure::Iterator anIts (anAncestor->myConnected); anIts.More(); anIts.Next())
-    {
-      if (anIts.Value() == this)
-      {
-        anAncestor->myConnected.Remove (anIts);
-        return;
-      }
-    }
-  }
-}
-
-// =======================================================================
-// function : UpdateStateWithAncestorStructures
-// purpose  :
-// =======================================================================
-void OpenGl_Structure::UpdateStateWithAncestorStructures() const
-{
-  myModificationState++;
-
-  for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
+  else if (myInstancedStructure != NULL)
   {
-    anIt.Value()->UpdateStateWithAncestorStructures();
+    return myInstancedStructure->IsRaytracable(); // instance structure
   }
-}
 
-// =======================================================================
-// function : UpdateRaytracableWithAncestorStructures
-// purpose  :
-// =======================================================================
-void OpenGl_Structure::UpdateRaytracableWithAncestorStructures() const
-{
-  myIsRaytracable = OpenGl_Raytrace::IsRaytracedStructure (this);
-
-  if (!myIsRaytracable)
-  {
-    for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
-    {
-      anIt.Value()->UpdateRaytracableWithAncestorStructures();
-    }
-  }
+  return Standard_False; // has no any groups or structures
 }
 
 // =======================================================================
-// function : SetRaytracableWithAncestorStructures
+// function : UpdateRaytracableState
 // purpose  :
 // =======================================================================
-void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
+void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
 {
-  myIsRaytracable = Standard_True;
+  myIsRaytracable = !toCheck || OpenGl_Raytrace::IsRaytracedStructure (this);
 
-  for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
+  if (IsRaytracable())
   {
-    if (!anIt.Value()->IsRaytracable())
-    {
-      anIt.Value()->SetRaytracableWithAncestorStructures();
-    }
+    ++myModificationState;
   }
 }
 
@@ -479,17 +388,17 @@ void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
 // =======================================================================
 void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
 {
-  OpenGl_Structure* aStruct = (OpenGl_Structure* )&theStructure;
-  Disconnect (theStructure);
-  myConnected.Append (aStruct);
+  OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
+
+  Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
+    "Error! Instanced structure is already defined");
+
+  myInstancedStructure = aStruct;
 
   if (aStruct->IsRaytracable())
   {
-    UpdateStateWithAncestorStructures();
-    SetRaytracableWithAncestorStructures();
+    UpdateStateIfRaytracable (Standard_False);
   }
-
-  aStruct->RegisterAncestorStructure (this);
 }
 
 // =======================================================================
@@ -498,22 +407,15 @@ void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
 // =======================================================================
 void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
 {
-  OpenGl_Structure* aStruct = (OpenGl_Structure* )&theStructure;
-  for (OpenGl_ListOfStructure::Iterator anIter (myConnected); anIter.More(); anIter.Next())
-  {
-    // Check for the given structure
-    if (anIter.Value() == aStruct)
-    {
-      myConnected.Remove (anIter);
+  OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
 
-      if (aStruct->IsRaytracable())
-      {
-        UpdateStateWithAncestorStructures();
-        UpdateRaytracableWithAncestorStructures();
-      }
+  if (myInstancedStructure == aStruct)
+  {
+    myInstancedStructure = NULL;
 
-      aStruct->UnregisterAncestorStructure (this);
-      return;
+    if (aStruct->IsRaytracable())
+    {
+      UpdateStateIfRaytracable();
     }
   }
 }
@@ -545,12 +447,14 @@ void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
     // Check for the given group
     if (aGroupIter.Value() == theGroup)
     {
+      const Standard_Boolean wasRaytracable =
+        static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
+
       theGroup->Clear (Standard_False);
 
-      if (((OpenGl_Group* )theGroup.operator->())->IsRaytracable())
+      if (wasRaytracable)
       {
-        UpdateStateWithAncestorStructures();
-        UpdateRaytracableWithAncestorStructures();
+        UpdateStateIfRaytracable();
       }
 
       myGroups.Remove (aGroupIter);
@@ -588,8 +492,7 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
 
   if (aRaytracableGroupDeleted)
   {
-    UpdateStateWithAncestorStructures();
-    UpdateRaytracableWithAncestorStructures();
+    myIsRaytracable = Standard_False;
   }
 
   Is2dText       = Standard_False;
@@ -651,12 +554,17 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
       aCtx->SetGlNormalizeEnabled (Standard_True);
     }
   }
-
-  // Apply transform persistence
-  const TEL_TRANSFORM_PERSISTENCE *aTransPersistence = NULL;
-  if ( myTransPers && myTransPers->mode != 0 )
+  if (TransformPersistence.Flags)
   {
-    aTransPersistence = theWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
+    OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
+    OpenGl_Mat4 aWorldView  = aCtx->WorldViewState.Current();
+    TransformPersistence.Apply (aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
+
+    aCtx->ProjectionState.Push();
+    aCtx->WorldViewState.Push();
+    aCtx->ProjectionState.SetCurrent (aProjection);
+    aCtx->WorldViewState.SetCurrent (aWorldView);
+    aCtx->ApplyProjectionMatrix();
   }
 
   // Take into account transform persistence
@@ -695,12 +603,10 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
   if (myHighlightColor)
     theWorkspace->HighlightColor = myHighlightColor;
 
-  // Render connected structures
-  OpenGl_ListOfStructure::Iterator anIter (myConnected);
-  while (anIter.More())
+  // Render instanced structure (if exists)
+  if (myInstancedStructure != NULL)
   {
-    anIter.Value()->RenderGeometry (theWorkspace);
-    anIter.Next();
+    myInstancedStructure->RenderGeometry (theWorkspace);
   }
 
   // Set up plane equations for non-structure transformed global model-view matrix
@@ -731,7 +637,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
   {
     // add planes at loaded view matrix state
-    aCtx->ChangeClipping().AddWorld (*aUserPlanes, theWorkspace);
+    aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
 
     // Set OCCT state uniform variables
     if (!aCtx->ShaderManager()->IsEmpty())
@@ -762,7 +668,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
   // Revert structure clippings
   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
   {
-    aCtx->ChangeClipping().Remove (*aUserPlanes);
+    aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);
 
     // Set OCCT state uniform variables
     if (!aCtx->ShaderManager()->IsEmpty())
@@ -771,12 +677,18 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
     }
   }
 
-  // Apply local transformation
+  // Restore local transformation
   if (myTransformation)
   {
     aCtx->ModelWorldState.Pop();
     aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
   }
+  if (TransformPersistence.Flags)
+  {
+    aCtx->ProjectionState.Pop();
+    aCtx->WorldViewState.Pop();
+    aCtx->ApplyProjectionMatrix();
+  }
 
   // Restore highlight color
   theWorkspace->HighlightColor = aHighlightColor;
@@ -787,12 +699,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
   theWorkspace->SetAspectMarker (anAspectMarker);
   theWorkspace->SetAspectText (anAspectText);
 
-  // Restore transform persistence
-  if ( myTransPers && myTransPers->mode != 0 )
-  {
-    theWorkspace->ActiveView()->BeginTransformPersistence (aCtx, aTransPersistence);
-  }
-
   // Apply highlight box
   if (!myHighlightBox.IsNull())
   {
@@ -816,9 +722,6 @@ void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
   clearHighlightColor (theGlCtx);
-
-  // Remove from connected list of ancestor
-  UnregisterFromAncestorStructure();
 }
 
 // =======================================================================