0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / PrsMgr / PrsMgr_Presentation.cxx
index dbd311d..c53573d 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <PrsMgr_Presentation.ixx>
-#include <PrsMgr_PresentationManager.hxx>
-#include <PrsMgr_Prs.hxx>
-#include <PrsMgr_ModedPresentation.hxx>
+#include <PrsMgr_Presentation.hxx>
 
-#include <Graphic3d_Structure.hxx>
-#include <Visual3d_View.hxx>
+#include <Graphic3d_DataStructureManager.hxx>
 #include <Precision.hxx>
+#include <Prs3d_Drawer.hxx>
+#include <PrsMgr_PresentableObject.hxx>
+#include <PrsMgr_PresentationManager.hxx>
+#include <Quantity_Color.hxx>
+#include <Graphic3d_CView.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(PrsMgr_Presentation, Graphic3d_Structure)
+
+namespace
+{
+  enum BeforeHighlightState
+  {
+    State_Empty,
+    State_Hidden,
+    State_Visible
+  };
+
+  static BeforeHighlightState StructureState (const Graphic3d_Structure* theStructure)
+  {
+    return !theStructure->IsDisplayed() ?
+      State_Empty : !theStructure->IsVisible() ?
+        State_Hidden : State_Visible;
+  }
+}
 
 //=======================================================================
 //function : PrsMgr_Presentation
 //purpose  :
 //=======================================================================
 PrsMgr_Presentation::PrsMgr_Presentation (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
-                                          const Handle(PrsMgr_PresentableObject)&     thePrsObject)
-: myPresentationManager (thePrsMgr),
-  myPresentableObject   (thePrsObject.operator->()),
-  myMustBeUpdated       (Standard_False),
-  myDisplayReason       (Standard_False)
-{
-  myStructure = new PrsMgr_Prs (thePrsMgr->StructureManager(),
-                                this, thePrsObject->TypeOfPresentation3d());
-  myStructure->SetOwner (myPresentableObject);
+                                          const Handle(PrsMgr_PresentableObject)& thePrsObject,
+                                          const Standard_Integer theMode)
+: Graphic3d_Structure (thePrsMgr->StructureManager()),
+  myPresentationManager  (thePrsMgr),
+  myPresentableObject    (thePrsObject.get()),
+  myBeforeHighlightState (State_Empty),
+  myMode                 (theMode),
+  myMustBeUpdated        (Standard_False)
+{
+  if (thePrsObject->TypeOfPresentation3d() == PrsMgr_TOP_ProjectorDependant)
+  {
+    SetVisual (Graphic3d_TOS_COMPUTED);
+  }
+  SetOwner (myPresentableObject);
+  SetMutable (myPresentableObject->IsMutable());
 }
 
 //=======================================================================
@@ -43,25 +69,24 @@ PrsMgr_Presentation::PrsMgr_Presentation (const Handle(PrsMgr_PresentationManage
 //=======================================================================
 void PrsMgr_Presentation::Display()
 {
-  Display (Standard_False);
-  myDisplayReason = Standard_False;
+  display (Standard_False);
+  myBeforeHighlightState = State_Visible;
 }
 
 //=======================================================================
-//function : Display
+//function : display
 //purpose  :
 //=======================================================================
-void PrsMgr_Presentation::Display (const Standard_Boolean theIsHighlight)
+void PrsMgr_Presentation::display (const Standard_Boolean theIsHighlight)
 {
-  if (!myStructure->IsDisplayed())
+  if (!base_type::IsDisplayed())
   {
-    myStructure->Display();
-    myDisplayReason = theIsHighlight;
+    base_type::SetIsForHighlight (theIsHighlight); // optimization - disable frustum culling for this presentation
+    base_type::Display();
   }
-  else if (!myStructure->IsVisible())
+  else if (!base_type::IsVisible())
   {
-    myStructure->SetVisible (Standard_True);
-    myDisplayReason = theIsHighlight;
+    base_type::SetVisible (Standard_True);
   }
 }
 
@@ -71,49 +96,52 @@ void PrsMgr_Presentation::Display (const Standard_Boolean theIsHighlight)
 //=======================================================================
 void PrsMgr_Presentation::Erase()
 {
-  if (myStructure.IsNull())
+  if (IsDeleted())
   {
     return;
   }
 
   // Erase structure from structure manager
-  myStructure->Erase();
-  myStructure->Clear();
+  erase();
+  clear (true);
   // Disconnect other structures
-  myStructure->DisconnectAll (Graphic3d_TOC_DESCENDANT);
+  DisconnectAll (Graphic3d_TOC_DESCENDANT);
   // Clear groups and remove graphic structure
-  myStructure.Nullify();
-}
-
-//=======================================================================
-//function : SetVisible
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::SetVisible (const Standard_Boolean theValue)
-{
-  myStructure->SetVisible (theValue);
+  Remove();
 }
 
 //=======================================================================
 //function : Highlight
 //purpose  :
 //=======================================================================
-void PrsMgr_Presentation::Highlight()
+void PrsMgr_Presentation::Highlight (const Handle(Prs3d_Drawer)& theStyle)
 {
-  Display (Standard_True);
-  myStructure->Highlight();
+  if (!IsHighlighted())
+  {
+    myBeforeHighlightState = StructureState (this);
+  }
+
+  display (Standard_True);
+  base_type::Highlight (theStyle);
 }
 
 //=======================================================================
 //function : Unhighlight
 //purpose  :
 //=======================================================================
-void PrsMgr_Presentation::Unhighlight() const
+void PrsMgr_Presentation::Unhighlight()
 {
-  myStructure->UnHighlight();
-  if (myDisplayReason)
+  base_type::UnHighlight();
+  switch (myBeforeHighlightState)
   {
-    myStructure->SetVisible (Standard_False);
+    case State_Visible:
+      return;
+    case State_Hidden:
+      base_type::SetVisible (Standard_False);
+      break;
+    case State_Empty:
+      base_type::erase();
+      break;
   }
 }
 
@@ -121,7 +149,7 @@ void PrsMgr_Presentation::Unhighlight() const
 //function : Clear
 //purpose  :
 //=======================================================================
-void PrsMgr_Presentation::Clear()
+void PrsMgr_Presentation::Clear (const Standard_Boolean theWithDestruction)
 {
   // This modification remove the contain of the structure:
   // Consequence:
@@ -129,271 +157,72 @@ void PrsMgr_Presentation::Clear()
   //    2. The speed for animation is constant
   //myPresentableObject = NULL;
   SetUpdateStatus (Standard_True);
-  if (myStructure.IsNull())
+  if (IsDeleted())
   {
     return;
   }
 
-  myStructure->Clear (Standard_True);
-  //  myStructure->Clear(Standard_False);
-  myStructure->RemoveAll();
-}
-
-//=======================================================================
-//function : Color
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Color (const Quantity_NameOfColor theColor)
-{
-  Display (Standard_True);
-  myStructure->Color (theColor);
-}
-
-//=======================================================================
-//function : BoundBox
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::BoundBox() const
-{
-  myStructure->BoundBox();
-}
-
-//=======================================================================
-//function : IsDisplayed
-//purpose  :
-//=======================================================================
-Standard_Boolean PrsMgr_Presentation::IsDisplayed() const
-{
-  return  myStructure->IsDisplayed()
-      &&  myStructure->IsVisible()
-      && !myDisplayReason;
-}
-
-//=======================================================================
-//function : IsHighlighted
-//purpose  :
-//=======================================================================
-Standard_Boolean PrsMgr_Presentation::IsHighlighted() const
-{
-  return myStructure->IsHighlighted();
-}
-
-//=======================================================================
-//function : DisplayPriority
-//purpose  :
-//=======================================================================
-Standard_Integer PrsMgr_Presentation::DisplayPriority() const
-{
-  return myStructure->DisplayPriority();
-}
-
-//=======================================================================
-//function : SetDisplayPriority
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::SetDisplayPriority (const Standard_Integer theNewPrior)
-{
-  myStructure->SetDisplayPriority (theNewPrior);
-}
-
-//=======================================================================
-//function : Connect
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Connect (const Handle(PrsMgr_Presentation)& theOther) const
-{
-  myStructure->Connect (theOther->Presentation());
-}
-
-//=======================================================================
-//function : Transform
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Transform (const Handle(Geom_Transformation)& theTrsf) const
-{
-  myStructure->Transform (theTrsf);
-}
-
-//=======================================================================
-//function : Place
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Place (const Quantity_Length theX,
-                                 const Quantity_Length theY,
-                                 const Quantity_Length theZ) const
-{
-  myStructure->Place (theX, theY, theZ);
-}
-
-//=======================================================================
-//function : Multiply
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Multiply (const Handle(Geom_Transformation)& theTrsf) const
-{
-  myStructure->Multiply (theTrsf);
-}
-
-//=======================================================================
-//function : Move
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Move (const Quantity_Length theX,
-                                const Quantity_Length theY,
-                                const Quantity_Length theZ) const
-{
-  myStructure->Move (theX, theY, theZ);
-}
-
-//=======================================================================
-//function : SetShadingAspect
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::SetShadingAspect (const Handle(Prs3d_ShadingAspect)& theShadingAspect) const
-{
-  myStructure->SetShadingAspect (theShadingAspect);
-}
-
-//=======================================================================
-//function : Compute
-//purpose  : Methods for hidden parts...
-//=======================================================================
-Handle(Graphic3d_Structure) PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector)
-{
-  Handle(Prs3d_Presentation) aPrs = new Prs3d_Presentation (myPresentationManager->StructureManager());
-  myPresentableObject->Compute (Projector (theProjector), aPrs);
-  return aPrs;
+  clear (theWithDestruction);
+  DisconnectAll (Graphic3d_TOC_DESCENDANT);
 }
 
 //=======================================================================
 //function : Compute
 //purpose  :
 //=======================================================================
-void PrsMgr_Presentation::Compute (const Handle(Graphic3d_Structure)& theStructure)
+void PrsMgr_Presentation::Compute()
 {
   Standard_Integer aDispMode = 0;
-  Standard_Integer aPresentationsNumber = myPresentableObject->myPresentations.Length();
-  for (Standard_Integer anIter = 1; anIter <= aPresentationsNumber; ++anIter)
+  for (PrsMgr_Presentations::Iterator aPrsIter (myPresentableObject->myPresentations); aPrsIter.More(); aPrsIter.Next())
   {
-    const PrsMgr_ModedPresentation& aModedPresentation = myPresentableObject->myPresentations.Value (anIter);
-    if (aModedPresentation.Presentation().operator->() == this)
+    const Handle(PrsMgr_Presentation)& aModedPresentation = aPrsIter.Value();
+    if (aModedPresentation == this)
     {
-      aDispMode = aModedPresentation.Mode();
+      aDispMode = aModedPresentation->Mode();
       break;
     }
   }
 
-  Handle(Prs3d_Presentation) aPrs3d = Handle(Prs3d_Presentation)::DownCast (theStructure);
-  myPresentableObject->Compute (myPresentationManager, aPrs3d, aDispMode);
+  myPresentableObject->Compute (myPresentationManager, this, aDispMode);
 }
 
 //=======================================================================
 //function : Compute
 //purpose  :
 //=======================================================================
-void PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector,
-                                   const Handle(Graphic3d_Structure)&            theStructToFill)
+void PrsMgr_Presentation::computeHLR (const Handle(Graphic3d_Camera)& theProjector,
+                                      Handle(Graphic3d_Structure)& theStructToFill)
 {
-  theStructToFill->Clear();
-  const Handle(Prs3d_Presentation)& aPrs = *((Handle(Prs3d_Presentation)* )&theStructToFill);
-  myPresentableObject->Compute (Projector (theProjector), aPrs);
-}
-
-//=======================================================================
-//function : Compute
-//purpose  :
-//=======================================================================
-Handle(Graphic3d_Structure) PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector,
-                                                          const Handle(Geom_Transformation)&            theTrsf)
-{
-  Handle(Prs3d_Presentation) aPrs3d = new Prs3d_Presentation (myPresentationManager->StructureManager());
-  if (theTrsf->Form() == gp_Translation)
+  if (theStructToFill.IsNull())
   {
-    myPresentableObject->Compute (Projector (theProjector), aPrs3d);
-    aPrs3d->Transform (theTrsf);
-    return aPrs3d;
+    theStructToFill = new Prs3d_Presentation (myPresentationManager->StructureManager());
   }
-
-  // waiting that something is done in gp_Trsf...rob
-  for (Standard_Integer i = 1; i <= 3; ++i)
-  {
-    for (Standard_Integer j = 1; j <= 3; ++j)
-    {
-      if (i != j)
-      {
-        if (Abs (theTrsf->Value (i, j)) > Precision::Confusion())
-        {
-          myPresentableObject->Compute (Projector (theProjector), theTrsf, aPrs3d);
-          return aPrs3d;
-        }
-      }
-    }
-  }
-
-  myPresentableObject->Compute (Projector (theProjector), aPrs3d);
-  aPrs3d->Transform (theTrsf);
-  return aPrs3d;
-}
-
-//=======================================================================
-//function : Compute
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Compute (const Handle(Graphic3d_DataStructureManager)& theProjector,
-                                   const Handle(Geom_Transformation)&            theTrsf,
-                                   const Handle(Graphic3d_Structure)&            theStructToFill)
-{
-  // recompute HLR after transformation in all the case
-  Handle(Prs3d_Presentation) aPrs = *((Handle(Prs3d_Presentation)*)&theStructToFill);
+  Handle(Graphic3d_Structure) aPrs = theStructToFill;
   theStructToFill->Clear();
-  myPresentableObject->Compute (Projector (theProjector), theTrsf, aPrs);
+  myPresentableObject->computeHLR (theProjector, Transformation(), aPrs);
 }
 
 //=======================================================================
-//function : Projector
+//function : ~PrsMgr_Presentation
 //purpose  :
 //=======================================================================
-Handle(Prs3d_Projector) PrsMgr_Presentation::Projector (const Handle(Graphic3d_DataStructureManager)& theProjector)
+PrsMgr_Presentation::~PrsMgr_Presentation()
 {
-  const Handle(Graphic3d_Camera)& aCamera = Handle(Visual3d_View)::DownCast (theProjector)->Camera();
-  const gp_Dir aDir = aCamera->Direction().Reversed();
-  const gp_Pnt anAt = aCamera->Center();
-  const gp_Dir anUp = aCamera->Up();
-  Handle(Prs3d_Projector) aProj = new Prs3d_Projector (!aCamera->IsOrthographic(),
-                                                       aCamera->Scale(),
-                                                       aDir.X(), aDir.Y(), aDir.Z(),
-                                                       anAt.X(), anAt.Y(), anAt.Z(),
-                                                       anUp.X(), anUp.Y(), anUp.Z());
-  return aProj;
+  Erase();
 }
 
-//=======================================================================
-//function : Destroy
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::Destroy()
+// =======================================================================
+// function : DumpJson
+// purpose  :
+// =======================================================================
+void PrsMgr_Presentation::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
 {
-  if (!myStructure.IsNull())
-  {
-    myStructure->Clear();
-    myStructure.Nullify();
-  }
-}
+  OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
+  OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Graphic3d_Structure)
 
-//=======================================================================
-//function : SetZLayer
-//purpose  :
-//=======================================================================
-void PrsMgr_Presentation::SetZLayer (Standard_Integer theLayerId)
-{
-  myStructure->SetZLayer (theLayerId);
-}
+  OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myPresentableObject)
 
-//=======================================================================
-//function : GetZLayer
-//purpose  :
-//=======================================================================
-Standard_Integer PrsMgr_Presentation::GetZLayer() const
-{
-  return myStructure->GetZLayer();
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myBeforeHighlightState)
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMode)
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMustBeUpdated)
 }