0024751: Performance improvements in the Edge/Edge intersection algorithm
[occt.git] / src / OpenGl / OpenGl_Group.cxx
index 4f4e2eb..d633227 100644 (file)
@@ -1,66 +1,87 @@
 // Created on: 2011-08-01
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
-#include <OpenGl_Group.hxx>
+#ifdef HAVE_CONFIG_H
+  #include <config.h>
+#endif
 
+#include <OpenGl_Group.hxx>
 #include <OpenGl_PrimitiveArray.hxx>
+#include <OpenGl_Structure.hxx>
 #include <OpenGl_Workspace.hxx>
 
-/*----------------------------------------------------------------------*/
-
-OpenGl_Group::OpenGl_Group ()
+// =======================================================================
+// function : OpenGl_Group
+// purpose  :
+// =======================================================================
+#ifndef HAVE_OPENCL
+OpenGl_Group::OpenGl_Group()
+#else
+OpenGl_Group::OpenGl_Group (const OpenGl_Structure* theAncestorStructure)
+#endif
 : myAspectLine(NULL),
   myAspectFace(NULL),
   myAspectMarker(NULL),
   myAspectText(NULL),
-  myFirst(NULL), myLast(NULL)
+  myFirst(NULL),
+  myLast(NULL)
 {
+#ifdef HAVE_OPENCL
+  myAncestorStructure = theAncestorStructure;
+  myIsRaytracable = Standard_False;
+  myModificationState = 0; // initial state
+#endif
 }
 
+// =======================================================================
+// function : ~OpenGl_Group
+// purpose  :
+// =======================================================================
 OpenGl_Group::~OpenGl_Group()
 {
   Release (Handle(OpenGl_Context)());
 }
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext,
+// =======================================================================
+// function : SetAspectLine
+// purpose  :
+// =======================================================================
+void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theAspect,
                                   const Standard_Boolean theIsGlobal)
 {
   if (theIsGlobal || myFirst == NULL)
   {
     if (myAspectLine == NULL)
+    {
       myAspectLine = new OpenGl_AspectLine();
-    myAspectLine->SetContext (theContext);
+    }
+    myAspectLine->SetAspect (theAspect);
   }
   else
   {
     OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
-    anAspectLine->SetContext (theContext);
-    AddElement (TelNil/*TelAspectLine*/, anAspectLine);
+    anAspectLine->SetAspect (theAspect);
+    AddElement (anAspectLine);
   }
 }
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
-                                  const CALL_DEF_CONTEXTFILLAREA& theAspect,
+// =======================================================================
+// function : SetAspectFace
+// purpose  :
+// =======================================================================
+void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect,
                                   const Standard_Boolean          theIsGlobal)
 {
   if (theIsGlobal || myFirst == NULL)
@@ -69,211 +90,142 @@ void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
     {
       myAspectFace = new OpenGl_AspectFace();
     }
-    myAspectFace->Init (theCtx, theAspect);
+    myAspectFace->SetAspect (theAspect);
   }
   else
   {
     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
-    anAspectFace->Init (theCtx, theAspect);
-    AddElement (TelNil/*TelAspectFace*/, anAspectFace);
+    anAspectFace->SetAspect (theAspect);
+    AddElement (anAspectFace);
   }
-}
 
-/*----------------------------------------------------------------------*/
+#ifdef HAVE_OPENCL
+  if (myIsRaytracable)
+  {
+    myModificationState++;
+
+    if (myAncestorStructure != NULL)
+    {
+      myAncestorStructure->UpdateStateWithAncestorStructures();
+    }
+  }
+#endif
+}
 
-void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theContext,
+// =======================================================================
+// function : SetAspectMarker
+// purpose  :
+// =======================================================================
+void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect,
                                     const Standard_Boolean theIsGlobal)
 {
   if (theIsGlobal || myFirst == NULL)
   {
     if (myAspectMarker == NULL)
+    {
       myAspectMarker = new OpenGl_AspectMarker();
-    myAspectMarker->SetContext (theContext);
+    }
+    myAspectMarker->SetAspect (theAspect);
   }
   else
   {
     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
-    anAspectMarker->SetContext (theContext);
-    AddElement (TelNil/*TelAspectMarker*/, anAspectMarker);
+    anAspectMarker->SetAspect (theAspect);
+    AddElement (anAspectMarker);
   }
 }
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext,
+// =======================================================================
+// function : SetAspectText
+// purpose  :
+// =======================================================================
+void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theAspect,
                                   const Standard_Boolean theIsGlobal)
 {
   if (theIsGlobal || myFirst == NULL)
   {
     if (myAspectText == NULL)
+    {
       myAspectText = new OpenGl_AspectText();
-    myAspectText->SetContext (theContext);
+    }
+    myAspectText->SetAspect (theAspect);
   }
   else
   {
     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
-    anAspectText->SetContext (theContext);
-    AddElement ( TelNil/*TelAspectText*/, anAspectText);
+    anAspectText->SetAspect (theAspect);
+    AddElement (anAspectText);
   }
 }
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
+// =======================================================================
+// function : AddElement
+// purpose  :
+// =======================================================================
+void OpenGl_Group::AddElement (OpenGl_Element* theElem)
 {
-  OpenGl_ElementNode *node = new OpenGl_ElementNode();
-
-  node->type = AType;
-  node->elem = AElem;
-  node->next = NULL;
-  (myLast? myLast->next : myFirst) = node;
-  myLast = node;
-}
+  OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
 
-/*----------------------------------------------------------------------*/
+  aNode->elem = theElem;
+  aNode->next = NULL;
+  (myLast? myLast->next : myFirst) = aNode;
+  myLast = aNode;
 
-void OpenGl_Group::RemovePrimitiveArray (const Handle(OpenGl_Context)& theGlCtx,
-                                         CALL_DEF_PARRAY*              thePArray)
-{
-  OpenGl_ElementNode *prevnode = NULL, *node = myFirst;
-  while (node != NULL)
+#ifdef HAVE_OPENCL
+  if (OpenGl_Raytrace::IsRaytracedElement (aNode))
   {
-    if (node->type == TelParray)
-    {
-      CALL_DEF_PARRAY* aCurPArray = ((const OpenGl_PrimitiveArray* )node->elem)->PArray();
+    myModificationState++;
+    myIsRaytracable = Standard_True;
 
-      // validate for correct pointer
-      if (aCurPArray->num_bounds  == thePArray->num_bounds  &&
-          aCurPArray->num_edges   == thePArray->num_edges   &&
-          aCurPArray->num_vertexs == thePArray->num_vertexs &&
-          aCurPArray->type        == thePArray->type)
-      {
-        (prevnode ? prevnode->next : myFirst) = node->next;
-        if (!myFirst) myLast = NULL;
-        OpenGl_Element::Destroy (theGlCtx, node->elem);
-        delete node;
-        break;
-      }
+    if (myAncestorStructure != NULL)
+    {
+      myAncestorStructure->UpdateStateWithAncestorStructures();
+      myAncestorStructure->SetRaytracableWithAncestorStructures();
     }
-    prevnode = node;
-    node = node->next;
   }
+#endif
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
   // Is rendering in ADD or IMMEDIATE mode?
-  const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
+  const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
 
   // Setup aspects
   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
-  if (myAspectLine)
-  {
-    theWorkspace->SetAspectLine (myAspectLine);
-  }
-  if (myAspectFace)
-  {
-    theWorkspace->SetAspectFace (myAspectFace);
-  }
-  if (myAspectMarker)
-  {
-    theWorkspace->SetAspectMarker (myAspectMarker);
-  }
-  if (myAspectText)
-  {
-    theWorkspace->SetAspectText (myAspectText);
-  }
+  Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
+  Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
+  Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
+  Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
 
   // Render group elements
-  Handle(OpenGl_Texture) aPrevTexture; // temporary disabled texture
   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
   {
-    switch (aNodeIter->type)
-    {
-      case TelPolyline:
-      case TelMarker:
-      case TelMarkerSet:
-      case TelText:
-      {
-        glDisable (GL_LIGHTING);
-
-        if (isImmediate)
-        {
-          glDepthMask (GL_FALSE);
-        }
-        else if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
-                 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) == 0 &&
-                  theWorkspace->DegenerateModel != 0)
-        {
-          glDisable (GL_DEPTH_TEST);
-          if (theWorkspace->NamedStatus & OPENGL_NS_TEXTURE)
-          {
-            aPrevTexture = theWorkspace->DisableTexture();
-          }
-          theWorkspace->NamedStatus |= OPENGL_NS_WIREFRAME;
-        }
-
-        if (!aPrevTexture.IsNull())
-        {
-          theWorkspace->EnableTexture (aPrevTexture);
-          aPrevTexture.Nullify();
-        }
-
-        aNodeIter->elem->Render (theWorkspace);
-        break;
-      }
-
-      case TelPolygon:
-      case TelPolygonIndices:
-      case TelQuadrangle:
-      case TelTriangleMesh:
-      {
-        if (isImmediate)
-        {
-          glDepthMask(GL_FALSE);
-        }
-        else if ((theWorkspace->NamedStatus & OPENGL_NS_ANIMATION) != 0 &&
-                 (theWorkspace->NamedStatus & OPENGL_NS_WIREFRAME) != 0 &&
-                  theWorkspace->DegenerateModel < 2)
-        {
-          glEnable (GL_DEPTH_TEST);
-          theWorkspace->NamedStatus &= ~OPENGL_NS_WIREFRAME;
-        }
-
-        if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
-        {
-          theWorkspace->DisablePolygonOffset();
-        }
-
-        aNodeIter->elem->Render (theWorkspace);
-
-        if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
-        {
-          theWorkspace->EnablePolygonOffset();
-        }
-        break;
-      }
-
-      default:
-      {
-        aNodeIter->elem->Render (theWorkspace);
-        break;
-      }
-    }
+    aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
   }
 
   // Restore aspects
-  theWorkspace->SetAspectLine   (aBackAspectLine);
-  theWorkspace->SetAspectFace   (aBackAspectFace);
-  theWorkspace->SetAspectMarker (aBackAspectMarker);
-  theWorkspace->SetAspectText   (aBackAspectText);
+  if (isLineSet)
+    theWorkspace->SetAspectLine (aBackAspectLine);
+  if (isFaceSet)
+    theWorkspace->SetAspectFace (aBackAspectFace);
+  if (isMarkerSet)
+    theWorkspace->SetAspectMarker (aBackAspectMarker);
+  if (isTextSet)
+    theWorkspace->SetAspectText (aBackAspectText);
 }
 
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
 {
   // Delete elements