0028047: Visualization - support objects with customized highlighting in AIS_Interact...
[occt.git] / src / SelectMgr / SelectMgr_SelectableObject.cxx
index e59069c..43a9118 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Standard_NotImplemented.hxx>
+#include <SelectMgr_SelectableObject.hxx>
 
-#include <SelectMgr_SelectableObject.ixx>
-#include <Standard_NoSuchObject.hxx>
-#include <SelectMgr_Selection.hxx>
-#include <Select3D_SensitiveEntity.hxx>
-#include <SelectBasics_EntityOwner.hxx>
-#include <SelectMgr_EntityOwner.hxx>
-#include <PrsMgr_PresentationManager3d.hxx>
-#include <Prs3d_Drawer.hxx>
-#include <Prs3d_LineAspect.hxx>
-#include <Prs3d_PointAspect.hxx>
 #include <Aspect_TypeOfMarker.hxx>
-#include <Prs3d_PlaneAspect.hxx>
+#include <Bnd_Box.hxx>
+#include <gp_Pnt.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
-
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_PlaneAspect.hxx>
+#include <Prs3d_PointAspect.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <PrsMgr_PresentableObjectPointer.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectBasics_EntityOwner.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <SelectMgr_SelectionManager.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_Type.hxx>
 #include <TopLoc_Location.hxx>
-#include <gp_Pnt.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectableObject,PrsMgr_PresentableObject)
 
 static Standard_Integer Search (const SelectMgr_SequenceOfSelection& seq,
                                 const Handle (SelectMgr_Selection)& theSel)
@@ -43,38 +50,43 @@ static Standard_Integer Search (const SelectMgr_SequenceOfSelection& seq,
   return ifound;
 } 
 
-
-
 //==================================================
-// Function: 
+// Function: SelectMgr_SelectableObject
 // Purpose :
 //==================================================
 
-SelectMgr_SelectableObject::SelectMgr_SelectableObject( const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
-  PrsMgr_PresentableObject (aTypeOfPresentation3d),
-  myDrawer                 (new Prs3d_Drawer()),
-  myHilightDrawer          (new Prs3d_Drawer()),
+SelectMgr_SelectableObject::SelectMgr_SelectableObject (const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
+: PrsMgr_PresentableObject (aTypeOfPresentation3d),
   myAssemblyOwner          (NULL),
-  myAutoHilight            (Standard_True)
+  myAutoHilight            (Standard_True),
+  myGlobalSelMode          (0)
 {
-  InitDefaultHilightAttributes (myHilightDrawer);
-  myHilightDrawer->Link (myDrawer);
+  //
 }
 
+//==================================================
+// Function: Destructor
+// Purpose : Clears all selections of the object
+//==================================================
+SelectMgr_SelectableObject::~SelectMgr_SelectableObject()
+{
+  for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); ++aSelIdx)
+  {
+    myselections.Value (aSelIdx)->Clear();
+  }
+}
 
 //==================================================
-// Function: 
+// Function: HasSelection
 // Purpose :
 //==================================================
-
-Standard_Boolean SelectMgr_SelectableObject
-::HasSelection(const Standard_Integer aMode) const
+Standard_Boolean SelectMgr_SelectableObject::HasSelection (const Standard_Integer theMode) const
 {
-  Standard_Boolean Found=Standard_False;
-  for (Standard_Integer I=1;I<= myselections.Length() && !Found;I++)
-    { if(((myselections.Value(I))->Mode())==aMode) 
-        return Standard_True;
-    }
+  for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); ++aSelIdx)
+  {
+    if (((myselections.Value (aSelIdx))->Mode()) == theMode)
+      return Standard_True;
+  }
   return Standard_False;
 }
 
@@ -108,6 +120,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives()
 //==================================================
 void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode)
 {
+  Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
+  Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
+
   for (Standard_Integer aSelIdx =1; aSelIdx <= myselections.Length(); aSelIdx++ )
   {
     if (myselections.Value (aSelIdx)->Mode() == theMode)
@@ -116,9 +131,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer the
       ComputeSelection (myselections (aSelIdx), theMode);
       myselections (aSelIdx)->UpdateStatus (SelectMgr_TOU_Partial);
       myselections (aSelIdx)->UpdateBVHStatus (SelectMgr_TBU_Renew);
-      if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && theMode == 0)
+      if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
       {
-        SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), theMode);
+        SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
       }
       return;
     }
@@ -127,9 +142,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer the
   Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
   ComputeSelection (aNewSel, theMode);
 
-  if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && theMode == 0)
+  if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
   {
-    SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), theMode);
+    SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
   }
 
   aNewSel->UpdateStatus (SelectMgr_TOU_Partial);
@@ -163,7 +178,6 @@ void SelectMgr_SelectableObject::ClearSelections(const Standard_Boolean update)
 const Handle(SelectMgr_Selection)& SelectMgr_SelectableObject
 ::Selection(const Standard_Integer aMode) const
 {
-  static Handle(SelectMgr_Selection) bidsel;
   Standard_Boolean Found = Standard_False;
   Standard_Integer Rank=0;
   for (Standard_Integer i=1;i<=myselections.Length() && !Found;i++)
@@ -207,9 +221,14 @@ void SelectMgr_SelectableObject
     myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
   }
 
-  if (Parent() != NULL && Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner() != NULL && aMode == 0)
+  if (aMode == 0)
   {
-    SetAssemblyOwner (Handle(SelectMgr_SelectableObject)::DownCast (Parent())->GetAssemblyOwner(), aMode);
+    Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
+    Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
+    if (! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
+    {
+      SetAssemblyOwner (aSelParent->GetAssemblyOwner(), aMode);
+    }
   }
 }
 
@@ -234,25 +253,20 @@ void SelectMgr_SelectableObject::ResetTransformation()
   PrsMgr_PresentableObject::ResetTransformation();
 }
 
-
 //=======================================================================
 //function : UpdateTransformation
 //purpose  : 
 //=======================================================================
-void SelectMgr_SelectableObject::UpdateTransformation() 
+void SelectMgr_SelectableObject::UpdateTransformation()
 {
-  
-  Handle(Select3D_SensitiveEntity) SE;
-  for(Init();More();Next()){
-    const Handle(SelectMgr_Selection) & Sel =  CurrentSelection();
-    Sel->UpdateStatus(SelectMgr_TOU_Partial);
-    Sel->UpdateBVHStatus (SelectMgr_TBU_Invalidate);
+  for (Init(); More(); Next())
+  {
+    CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
   }
-  PrsMgr_PresentableObject::UpdateTransformation();
 
+  PrsMgr_PresentableObject::UpdateTransformation();
 }
 
-
 //=======================================================================
 //function : UpdateTransformation
 //purpose  : 
@@ -295,14 +309,22 @@ void SelectMgr_SelectableObject::ClearSelected ()
     mySelectionPrs->Clear();
 }
 
+//=======================================================================
+//function : ClearDynamicHighlight
+//purpose  :
+//=======================================================================
+void SelectMgr_SelectableObject::ClearDynamicHighlight (const Handle(PrsMgr_PresentationManager3d)& theMgr)
+{
+  theMgr->ClearImmediateDraw();
+}
+
 //=======================================================================
 //function : HilightOwnerWithColor
 //purpose  : 
 //=======================================================================
-void SelectMgr_SelectableObject::HilightOwnerWithColor 
-  ( const Handle(PrsMgr_PresentationManager3d)&,
-    const Quantity_NameOfColor,
-    const Handle(SelectMgr_EntityOwner)&)
+void SelectMgr_SelectableObject::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)&,
+                                                        const Handle(Prs3d_Drawer)&,
+                                                        const Handle(SelectMgr_EntityOwner)&)
 {
   Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightOwnerWithColor");
 }
@@ -329,14 +351,13 @@ void SelectMgr_SelectableObject::SetAutoHilight ( const Standard_Boolean newAuto
 //function : GetHilightPresentation
 //purpose  : 
 //=======================================================================
-Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
+Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation (const Handle(PrsMgr_PresentationManager3d)& theMgr)
 {
-  if( myHilightPrs.IsNull() && !TheMgr.IsNull() )
-    {
-      myHilightPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
-      myHilightPrs->SetTransformPersistence( GetTransformPersistenceMode(), 
-                                        GetTransformPersistencePoint() );
-    }
+  if (myHilightPrs.IsNull() && !theMgr.IsNull())
+  {
+    myHilightPrs = new Prs3d_Presentation (theMgr->StructureManager());
+    myHilightPrs->SetTransformPersistence (TransformPersistence());
+  }
 
   return myHilightPrs;
 }
@@ -346,13 +367,14 @@ Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation( c
 //function : GetSelectPresentation
 //purpose  : 
 //=======================================================================
-Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
+Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation (const Handle(PrsMgr_PresentationManager3d)& theMgr)
 {
-  if( mySelectionPrs.IsNull() && !TheMgr.IsNull() ) {
-    mySelectionPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
-    mySelectionPrs->SetTransformPersistence( GetTransformPersistenceMode(), 
-                                            GetTransformPersistencePoint() );
+  if (mySelectionPrs.IsNull() && !theMgr.IsNull())
+  {
+    mySelectionPrs = new Prs3d_Presentation (theMgr->StructureManager());
+    mySelectionPrs->SetTransformPersistence (TransformPersistence());
   }
+
   return mySelectionPrs;
 }
 
@@ -392,12 +414,12 @@ void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId)
 }
 
 //=======================================================================
-//function : UpdateSelection
+//function : updateSelection
 //purpose  : Sets update status FULL to selections of the object. Must be
 //           used as the only method of UpdateSelection from outer classes
 //           to prevent BVH structures from being outdated.
 //=======================================================================
-void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode)
+void SelectMgr_SelectableObject::updateSelection (const Standard_Integer theMode)
 {
   if (theMode == -1)
   {
@@ -420,120 +442,6 @@ void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode
   }
 }
 
-//=======================================================================
-//function : SetAttributes
-//purpose  : 
-//=======================================================================
-void SelectMgr_SelectableObject::SetAttributes (const Handle(Prs3d_Drawer)& theDrawer)
-{
-  myDrawer = theDrawer;
-}
-
-//=======================================================================
-//function : UnsetAttributes
-//purpose  : 
-//=======================================================================
-void SelectMgr_SelectableObject::UnsetAttributes()
-{
-  Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
-  if (myDrawer->HasLink())
-  {
-    aDrawer->Link (myDrawer->Link());
-  }
-  myDrawer = aDrawer;
-}
-
-//=======================================================================
-//function : SetHilightAttributes
-//purpose  :
-//=======================================================================
-void SelectMgr_SelectableObject::SetHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
-{
-  myHilightDrawer = theDrawer;
-}
-
-//=======================================================================
-//function : UnsetAttributes
-//purpose  :
-//=======================================================================
-void SelectMgr_SelectableObject::UnsetHilightAttributes()
-{
-  Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
-  InitDefaultHilightAttributes (aDrawer);
-  aDrawer->Link (myDrawer);
-  myHilightDrawer = aDrawer;
-}
-
-//=======================================================================
-//function : InitDefaultHilightAttributes
-//purpose  :
-//=======================================================================
-void SelectMgr_SelectableObject::InitDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
-{
-  if (!theDrawer->HasOwnPointAspect())
-  {
-    theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
-    if (theDrawer->HasLink())
-    {
-      *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
-    }
-  }
-  if (!theDrawer->HasOwnLineAspect())
-  {
-    theDrawer->SetLineAspect  (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    if (theDrawer->HasLink())
-    {
-      *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
-    }
-  }
-  if (!theDrawer->HasOwnWireAspect())
-  {
-    theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    if (theDrawer->HasLink())
-    {
-      *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
-    }
-  }
-  if (!theDrawer->HasOwnPlaneAspect())
-  {
-    theDrawer->SetPlaneAspect (new Prs3d_PlaneAspect());
-    if (theDrawer->HasLink())
-    {
-      *theDrawer->PlaneAspect()->EdgesAspect() = *theDrawer->Link()->PlaneAspect()->EdgesAspect();
-    }
-  }
-  if (!theDrawer->HasOwnFreeBoundaryAspect())
-  {
-    theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    if (theDrawer->HasLink())
-    {
-      *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
-    }
-  }
-  if (!theDrawer->HasOwnUnFreeBoundaryAspect())
-  {
-    theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
-    if (theDrawer->HasLink())
-    {
-      *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
-    }
-  }
-
-  theDrawer->WireAspect()->SetWidth(2.);
-  theDrawer->LineAspect()->SetWidth(2.);
-  theDrawer->PlaneAspect()->EdgesAspect()->SetWidth(2.);
-  theDrawer->FreeBoundaryAspect()->SetWidth(2.);
-  theDrawer->UnFreeBoundaryAspect()->SetWidth(2.);
-  theDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_POINT);
-  theDrawer->PointAspect()->SetScale(2.);
-
-  // By default the hilight drawer has absolute type of deflection.
-  // It is supposed that absolute deflection is taken from Link().
-  // It is necessary to use for all sub-shapes identical coefficient
-  // computed in ::Compute() call for whole shape and stored in base drawer.
-  theDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
-}
-
 //=======================================================================
 //function : SetAssemblyOwner
 //purpose  : Sets common entity owner for assembly sensitive object entities
@@ -583,16 +491,14 @@ const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwne
 
 //=======================================================================
 //function : BndBoxOfSelected
-//purpose  : Returns a bounding box of sensitive entities with the owners given
-//           if they are a part of activated selection
+//purpose  :
 //=======================================================================
-Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
+Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (const Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
 {
-  Bnd_Box aBnd;
-
   if (theOwners->IsEmpty())
-    return aBnd;
+    return Bnd_Box();
 
+  Bnd_Box aBnd;
   for (Init(); More(); Next())
   {
     const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
@@ -606,23 +512,33 @@ Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (Handle(SelectMgr_IndexedMa
       if (theOwners->Contains (anOwner))
       {
         Select3D_BndBox3d aBox = aSel->Sensitive()->BaseSensitive()->BoundingBox();
-        Bnd_Box aTmpBnd;
-        aTmpBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
-                        aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
-        aBnd.Add (aTmpBnd);
-
-        Standard_Integer anOwnerIdx = theOwners->FindIndex (anOwner);
-        if (theOwners->Size() != anOwnerIdx)
-        {
-          theOwners->Swap (anOwnerIdx, theOwners->Size());
-        }
-        theOwners->RemoveLast();
-
-        if (theOwners->IsEmpty())
-          return aBnd;
+        aBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
+                     aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
       }
     }
   }
 
   return aBnd;
 }
+
+//=======================================================================
+//function : GlobalSelOwner
+//purpose  : Returns entity owner corresponding to selection of the object as a whole
+//=======================================================================
+Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
+{
+   Handle(SelectMgr_EntityOwner) anOwner;
+
+  if (!HasSelection (myGlobalSelMode))
+    return anOwner;
+
+  const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
+  if (aGlobalSel->IsEmpty())
+    return anOwner;
+
+  aGlobalSel->Init();
+  anOwner =
+    Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Sensitive()->BaseSensitive()->OwnerId());
+
+  return anOwner;
+}