0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / AIS / AIS_ConnectedInteractive.cxx
index 19b40aa..4f74b25 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Standard_NotImplemented.hxx>
 
-#include <AIS_ConnectedInteractive.ixx>
-#include <SelectMgr_EntityOwner.hxx>
-#include <Select3D_SensitiveEntity.hxx>
+#include <AIS_ConnectedInteractive.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_InteractiveObject.hxx>
+#include <AIS_Shape.hxx>
+#include <BRepTools.hxx>
 #include <Geom_Transformation.hxx>
-
+#include <gp_Trsf.hxx>
+#include <NCollection_DataMap.hxx>
+#include <Precision.hxx>
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Prs3d_Projector.hxx>
 #include <PrsMgr_ModedPresentation.hxx>
-#include <PrsMgr_Presentation3d.hxx>
-#include <OSD_Timer.hxx>
+#include <PrsMgr_Presentation.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_ProgramError.hxx>
+#include <Standard_Type.hxx>
+#include <StdPrs_HLRPolyShape.hxx>
+#include <StdPrs_WFShape.hxx>
+#include <StdSelect.hxx>
+#include <StdSelect_BRepOwner.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_OrientedShapeMapHasher.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(AIS_ConnectedInteractive,AIS_InteractiveObject)
 
 //=======================================================================
 //function : AIS_ConnectedInteractive
@@ -32,7 +52,7 @@
 //=======================================================================
 AIS_ConnectedInteractive::AIS_ConnectedInteractive(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
 AIS_InteractiveObject(aTypeOfPresentation3d)
-{    
+{
   SetHilightMode(0);
 }
 
@@ -41,61 +61,72 @@ AIS_InteractiveObject(aTypeOfPresentation3d)
 //purpose  : 
 //=======================================================================
 AIS_KindOfInteractive AIS_ConnectedInteractive::Type() const
-{return AIS_KOI_Object;}
+{
+  return AIS_KOI_Object;
+}
 
 Standard_Integer AIS_ConnectedInteractive::Signature() const
-{return 0; }
-
-
+{
+  return 0;
+}
 
 
 //=======================================================================
 //function : Connect
 //purpose  : 
 //=======================================================================
-void AIS_ConnectedInteractive::
-Connect(const Handle(AIS_InteractiveObject)& anotherIObj)
+void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj)
 {
-  // To have the time to Disconnect below, 
-  // the old is kept for a while. 
-  if(myReference==anotherIObj) return;
-  myOldReference = myReference;
-//Disconnect();
-  myReference = anotherIObj ;
+  if (myReference == theAnotherObj) return;
+
+  Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (theAnotherObj);
+  if (!aConnected.IsNull())
+  {
+    myReference = aConnected->myReference;
+  }
+  else if (theAnotherObj->HasOwnPresentations())
+  {
+    myReference = theAnotherObj;
+  }
+  else
+  {
+    Standard_ProgramError::Raise ("AIS_ConnectedInteractive::Connect() - object without own presentation can not be connected");
+  }
+
+  if (!myReference.IsNull())
+  {
+    myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
+  }
 }
 
 //=======================================================================
 //function : Connect
 //purpose  : 
 //=======================================================================
-void AIS_ConnectedInteractive::
-Connect(const Handle(AIS_InteractiveObject)& anotherIobj, 
-       const TopLoc_Location& aLocation)
+void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj, 
+                                        const gp_Trsf&                       theLocation)
 {
-  if(myLocation!=aLocation)
-    myLocation = aLocation;
-  if(myReference!=anotherIobj) {
-    myOldReference = myReference; // necessary to disconnect below..
-//  Disconnect();
-    myReference = anotherIobj;}
-  
+  Connect (theAnotherObj);
+
+  SetLocalTransformation (theLocation);
 }
 
 
 //=======================================================================
 //function : Disconnect
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void AIS_ConnectedInteractive::Disconnect()
 {
-  for(Standard_Integer i =1;i<=myPresentations.Length();i++)
+  for(Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
+  {
+    const Handle(PrsMgr_Presentation)& aPrs = myPresentations (aPrsIter).Presentation();
+    if (!aPrs.IsNull())
     {
-      Handle(PrsMgr_Presentation3d) P = Handle(PrsMgr_Presentation3d)::DownCast(myPresentations(i).Presentation());
-      if(!P.IsNull()) {
-       P->Presentation()->DisconnectAll(Graphic3d_TOC_DESCENDANT);
-      }
+      aPrs->Presentation()->DisconnectAll (Graphic3d_TOC_DESCENDANT);
     }
+  }
 }
 //=======================================================================
 //function : Compute
@@ -105,11 +136,6 @@ void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3
                                         const Handle(Prs3d_Presentation)&           thePrs,
                                         const Standard_Integer                      theMode)
 {
-  if (!(HasLocation() || HasConnection()))
-  {
-    return;
-  }
-
   if (HasConnection())
   {
     thePrs->Clear (Standard_False);
@@ -126,77 +152,243 @@ void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3
     }
   }
 
-  if (HasLocation())
+  if (!thePrs.IsNull())
   {
-    Handle(Geom_Transformation) aPrsTrans = new Geom_Transformation (myLocation.Transformation());
-    thePrsMgr->Transform (this, aPrsTrans, theMode);
+    thePrs->ReCompute();
   }
-  thePrs->ReCompute();
 }
 
-void AIS_ConnectedInteractive::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
+//=======================================================================
+//function : Compute
+//purpose  :
+//=======================================================================
+void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
+                                        const Handle(Geom_Transformation)& theTransformation,
+                                        const Handle(Prs3d_Presentation)& thePresentation)
 {
-// Standard_NotImplemented::Raise("AIS_ConnectedInteractive::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
-  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
+  updateShape (Standard_False);
+  if (myShape.IsNull())
+  {
+    return;
+  }
+  const TopLoc_Location& aLocation = myShape.Location();
+  TopoDS_Shape aShape = myShape.Located (TopLoc_Location (theTransformation->Trsf()) * aLocation);
+  Compute (theProjector, thePresentation, aShape);
 }
 
-void AIS_ConnectedInteractive::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Prs3d_Presentation& aPresentation)
+//=======================================================================
+//function : Compute
+//purpose  :
+//=======================================================================
+void AIS_ConnectedInteractive::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)
 {
-// Standard_NotImplemented::Raise("AIS_ConnectedInteractive::Compute(const Handle_Prs3d_Projector&, const Handle_Prs3d_Presentation&)");
PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
+  updateShape (Standard_True);
 Compute (aProjector, aPresentation, myShape);
 }
 
 //=======================================================================
-//function : ComputeSelection
-//purpose  : 
+//function : Compute
+//purpose  :
 //=======================================================================
-
-void AIS_ConnectedInteractive::ComputeSelection(const Handle(SelectMgr_Selection)& aSel, 
-                                                const Standard_Integer aMode)
+void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
+                                        const Handle(Prs3d_Presentation)& thePresentation,
+                                        const TopoDS_Shape& theShape)
 {
-  if(!(HasLocation() ||HasConnection())) return;
-  
-  aSel->Clear();
-  if(!myReference->HasSelection(aMode))
-    myReference->UpdateSelection(aMode);
+  if (myShape.IsNull())
+  {
+    return;
+  }
 
-  const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection(aMode);
-  Handle(SelectMgr_EntityOwner) OWN = new SelectMgr_EntityOwner(this);
-  Handle(Select3D_SensitiveEntity) SE3D, SNew;
-  
-  if(TheRefSel->IsEmpty())
-    myReference->UpdateSelection(aMode);
-  for(TheRefSel->Init();TheRefSel->More();TheRefSel->Next())
+  switch (theShape.ShapeType())
   {
-    SE3D = Handle(Select3D_SensitiveEntity)::DownCast(TheRefSel->Sensitive());
-    if(!SE3D.IsNull())
+    case TopAbs_VERTEX:
+    case TopAbs_EDGE:
+    case TopAbs_WIRE:
     {
-      // Get the copy of SE3D
-      SNew = SE3D->GetConnected(myLocation);
-      if(aMode==0)
+      thePresentation->SetDisplayPriority (4);
+      StdPrs_WFShape::Add (thePresentation, theShape, myDrawer);
+      break;
+    }
+    default:
+    {
+      Handle(Prs3d_Drawer) aDefaultDrawer = GetContext()->DefaultDrawer();
+      if (aDefaultDrawer->DrawHiddenLine()) 
       {
-        SNew->Set(OWN);
-        // In case if SE3D caches some location-dependent data
-        // that must be updated after setting OWN
-        SNew->SetLocation(myLocation);
+        myDrawer->EnableDrawHiddenLine();
       }
-      aSel->Add(SNew);
+      else 
+      {
+        myDrawer->DisableDrawHiddenLine();
+      }
+      
+      Aspect_TypeOfDeflection aPrevDeflection = aDefaultDrawer->TypeOfDeflection();
+      aDefaultDrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
+
+      // process HLRAngle and HLRDeviationCoefficient()
+      Standard_Real aPrevAngle = myDrawer->HLRAngle();
+      Standard_Real aNewAngle = aDefaultDrawer->HLRAngle();
+      if (myDrawer->IsAutoTriangulation() &&
+          Abs (aNewAngle - aPrevAngle) > Precision::Angular())
+      {
+        BRepTools::Clean (theShape);
+      }
+
+      myDrawer->SetHLRAngle (aNewAngle);
+      myDrawer->SetHLRDeviationCoefficient (aDefaultDrawer->HLRDeviationCoefficient());
+      StdPrs_HLRPolyShape::Add (thePresentation, theShape, myDrawer, theProjector);
+      aDefaultDrawer->SetTypeOfDeflection (aPrevDeflection);
     }
   }
 }
 
-void AIS_ConnectedInteractive::UpdateLocation()
+//=======================================================================
+//function : updateShape
+//purpose  : 
+//=======================================================================
+void AIS_ConnectedInteractive::updateShape (const Standard_Boolean isWithLocation)
 {
-// Standard_NotImplemented::Raise("AIS_ConnectedInteractive::UpdateLocation()");
- SelectMgr_SelectableObject::UpdateLocation() ;
+  Handle(AIS_Shape) anAisShape = Handle(AIS_Shape)::DownCast (myReference);
+  if (anAisShape.IsNull())
+  {
+    return;
+  }
+  TopoDS_Shape aShape = anAisShape->Shape();
+  if (aShape.IsNull())
+  {
+    return;
+  }
+
+  if(!isWithLocation)
+  {
+    myShape = aShape;
+  }
+  else
+  {
+    myShape = aShape.Moved (TopLoc_Location (Transformation()));
+  }
 }
-void AIS_ConnectedInteractive::UpdateLocation(const Handle(SelectMgr_Selection)& Sel)
+
+//=======================================================================
+//function : ComputeSelection
+//purpose  : 
+//=======================================================================
+void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, 
+                                                 const Standard_Integer theMode)
 {
-// Standard_NotImplemented::Raise("AIS_ConnectedInteractive::UpdateLocation(const Handle(SelectMgr_Selection)& Sel)");
- SelectMgr_SelectableObject::UpdateLocation(Sel) ;
+  if (!HasConnection())
+  {
+    return;
+  }
+
+  if (theMode != 0 && myReference->AcceptShapeDecomposition())
+  {
+    computeSubShapeSelection (theSelection, theMode);
+    return;
+  }
+
+  if (!myReference->HasSelection (theMode))
+  {
+    myReference->RecomputePrimitives (theMode);
+  }
+
+  const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection (theMode);
+  Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
+  Handle(Select3D_SensitiveEntity) aSensitive, aNewSensitive;
+
+  TopLoc_Location aLocation (Transformation());
+  anOwner->SetLocation (aLocation);
+
+  if (TheRefSel->IsEmpty())
+  {
+    myReference->RecomputePrimitives (theMode);
+  }
+
+  for (TheRefSel->Init(); TheRefSel->More(); TheRefSel->Next())
+  {
+    aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (TheRefSel->Sensitive()->BaseSensitive());
+    if (!aSensitive.IsNull())
+    {
+      // Get the copy of SE3D
+      aNewSensitive = aSensitive->GetConnected();
+
+      aNewSensitive->Set(anOwner);
+
+      theSelection->Add (aNewSensitive);
+    }
+  }
 }
-/*void AIS_ConnectedInteractive::UpdateLocation(const Handle_Prs3d_Presentation& aPresentation)
+
+//=======================================================================
+//function : ComputeSubShapeSelection 
+//purpose  :
+//=======================================================================
+void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_Selection)& theSelection, 
+                                                         const Standard_Integer theMode)
 {
-// Standard_NotImplemented::Raise("AIS_ConnectedInteractive::UpdateLocation(const Handle_Prs3d_Presentation&)");
- SelectMgr_SelectableObject::UpdateLocation(aPresentation) ;
-}*/
+  typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
+  typedef NCollection_DataMap<TopoDS_Shape, SensitiveList, TopTools_OrientedShapeMapHasher>
+    Shapes2EntitiesMap;
+
+  if (!myReference->HasSelection (theMode))
+    myReference->RecomputePrimitives (theMode);
+   
+  const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode);
+
+  if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full)
+  {
+    myReference->RecomputePrimitives (theMode);
+  }
+  
+  Handle(StdSelect_BRepOwner) anOwner;
+  TopLoc_Location aDummyLoc;
+
+  Handle(Select3D_SensitiveEntity) aSE, aNewSE;
+  Shapes2EntitiesMap aShapes2EntitiesMap;
+
+  SensitiveList aSEList;
+  TopoDS_Shape aSubShape;
+
+  // Fill in the map of subshapes and corresponding 
+  // sensitive entities associated with aMode 
+  for (aRefSel->Init(); aRefSel->More(); aRefSel->Next())
+  {
+    aSE = Handle(Select3D_SensitiveEntity)::DownCast (aRefSel->Sensitive()->BaseSensitive());
+    if(!aSE.IsNull())
+    {
+      anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId());
+      if(!anOwner.IsNull())
+      {
+        aSubShape = anOwner->Shape(); 
+        if(!aShapes2EntitiesMap.IsBound (aSubShape))
+        {
+          aShapes2EntitiesMap.Bind (aSubShape, aSEList);
+        }
+        aShapes2EntitiesMap (aSubShape).Append (aSE);
+      }
+    }
+  }
+
+  // Fill in selection from aShapes2EntitiesMap
+  for (Shapes2EntitiesMap::Iterator aMapIt (aShapes2EntitiesMap); aMapIt.More(); aMapIt.Next())
+  {
+    aSEList = aMapIt.Value();
+    anOwner = new StdSelect_BRepOwner (aMapIt.Key(), 
+                                       this, 
+                                       aSEList.First()->OwnerId()->Priority(), 
+                                       Standard_True);
+    anOwner->SetLocation (Transformation());
+
+    for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
+    {
+      aSE = aListIt.Value();
+
+      aNewSE = aSE->GetConnected();
+      aNewSE->Set (anOwner);
+
+      theSelection->Add (aNewSE);
+    }
+  }
+
+  StdSelect::SetDrawerForBRepOwner (theSelection, myDrawer);  
+}