0027732: Visualization - AIS_ConnectedInteractive crashes on NULL handle returned...
authorkgv <kgv@opencascade.com>
Tue, 13 Mar 2018 14:54:11 +0000 (17:54 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 22 Mar 2018 16:51:29 +0000 (19:51 +0300)
Added NULL-check to AIS_ConnectedInteractive::ComputeSelection().
Added missing interface methods MeshVS_Mesh::AcceptDisplayMode()
and MeshVS_CommonSensitiveEntity::GetConnected().

src/AIS/AIS_ConnectedInteractive.cxx
src/MeshVS/MeshVS_CommonSensitiveEntity.cxx
src/MeshVS/MeshVS_CommonSensitiveEntity.hxx
src/MeshVS/MeshVS_Mesh.cxx
src/MeshVS/MeshVS_Mesh.hxx

index 8958a55..6a655f6 100644 (file)
@@ -223,7 +223,6 @@ void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selectio
 
   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);
@@ -235,15 +234,14 @@ void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selectio
 
   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (TheRefSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
   {
-    aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (aSelEntIter.Value()->BaseSensitive());
-    if (!aSensitive.IsNull())
+    if (Handle(Select3D_SensitiveEntity) aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (aSelEntIter.Value()->BaseSensitive()))
     {
       // Get the copy of SE3D
-      aNewSensitive = aSensitive->GetConnected();
-
-      aNewSensitive->Set(anOwner);
-
-      theSelection->Add (aNewSensitive);
+      if (Handle(Select3D_SensitiveEntity) aNewSensitive = aSensitive->GetConnected())
+      {
+        aNewSensitive->Set(anOwner);
+        theSelection->Add (aNewSensitive);
+      }
     }
   }
 }
@@ -296,10 +294,11 @@ void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_
     anOwner->SetLocation (Transformation());
     for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
     {
-      Handle(Select3D_SensitiveEntity) aSE = aListIt.Value();
-      Handle(Select3D_SensitiveEntity) aNewSE = aSE->GetConnected();
-      aNewSE->Set (anOwner);
-      theSelection->Add (aNewSE);
+      if (Handle(Select3D_SensitiveEntity) aNewSE = aListIt.Value()->GetConnected())
+      {
+        aNewSE->Set (anOwner);
+        theSelection->Add (aNewSE);
+      }
     }
   }
 
index ebe36dd..6362d8c 100644 (file)
@@ -88,6 +88,22 @@ MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const Handle(SelectB
 }
 
 //=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+MeshVS_CommonSensitiveEntity::MeshVS_CommonSensitiveEntity (const MeshVS_CommonSensitiveEntity& theOther)
+: Select3D_SensitiveSet (theOther.myOwnerId),
+  myDataSource (theOther.myDataSource),
+  myItemIndexes (theOther.myItemIndexes),
+  mySelMethod (theOther.mySelMethod),
+  myMaxFaceNodes (theOther.myMaxFaceNodes),
+  myCOG (theOther.myCOG),
+  myBndBox (theOther.myBndBox)
+{
+  //
+}
+
+//=======================================================================
 //function : Destructor
 //purpose  :
 //=======================================================================
index 5f36d68..ef1e07c 100644 (file)
@@ -24,6 +24,7 @@
 //! Sensitive entity covering entire mesh for global selection.
 class MeshVS_CommonSensitiveEntity : public Select3D_SensitiveSet
 {
+  DEFINE_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
 public:
 
   //! Default constructor.
@@ -58,9 +59,8 @@ public:
   //! Returns center of a mesh
   Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
 
-public:
-
-  DEFINE_STANDARD_RTTIEXT (MeshVS_CommonSensitiveEntity, Select3D_SensitiveSet)
+  //! Create a copy.
+  virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE { return new MeshVS_CommonSensitiveEntity (*this); }
 
 protected:
 
@@ -76,6 +76,9 @@ protected:
   //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
   Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
 
+  //! Protected copy constructor.
+  Standard_EXPORT MeshVS_CommonSensitiveEntity (const MeshVS_CommonSensitiveEntity& theOther);
+
 private:
 
   //! Return point for specified index.
index 59b28e5..1df8533 100644 (file)
@@ -138,6 +138,33 @@ MeshVS_Mesh::MeshVS_Mesh (const Standard_Boolean theIsAllowOverlapped )
 }
 
 //================================================================
+// Function : AcceptDisplayMode
+// Purpose  :
+//================================================================
+Standard_Boolean MeshVS_Mesh::AcceptDisplayMode (const Standard_Integer theMode) const
+{
+  if (theMode <= 0)
+  {
+    return Standard_False;
+  }
+  else if (myBuilders.IsEmpty())
+  {
+    return Standard_True;
+  }
+
+  for (MeshVS_SequenceOfPrsBuilder::Iterator aBuilderIter (myBuilders); aBuilderIter.More(); aBuilderIter.Next())
+  {
+    Handle(MeshVS_PrsBuilder) aBuilder = aBuilderIter.Value();
+    if (!aBuilder.IsNull()
+      && aBuilder->TestFlags (theMode))
+    {
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//================================================================
 // Function : Compute
 // Purpose  :
 //================================================================
@@ -145,56 +172,55 @@ void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMg
                             const Handle(Prs3d_Presentation)& thePresentation,
                             const Standard_Integer theMode )
 {
-  OSD_Timer gTimer;
-
-  Standard_Boolean ShowComputeTime = Standard_True;
-  myCurrentDrawer->GetBoolean( MeshVS_DA_ComputeTime, ShowComputeTime );
-
-  if ( ShowComputeTime )
+  Standard_Boolean toShowComputeTime = Standard_True;
+  myCurrentDrawer->GetBoolean (MeshVS_DA_ComputeTime, toShowComputeTime);
+  OSD_Timer aTimer;
+  if (toShowComputeTime)
   {
-    gTimer.Reset();
-    gTimer.Start();
+    aTimer.Reset();
+    aTimer.Start();
   }
 
   // Repair Ids in map if necessary
   Handle( MeshVS_DataSource ) aDS = GetDataSource();
-  if ( aDS.IsNull() )
+  if (aDS.IsNull()
+   || theMode <= 0)
+  {
     return;
+  }
 
   const TColStd_PackedMapOfInteger& aNodes = aDS->GetAllNodes();
   const TColStd_PackedMapOfInteger& aElems = aDS->GetAllElements();
-  Standard_Boolean HasNodes    = !aNodes.IsEmpty(),
-                   HasElements = !aElems.IsEmpty();
+  const Standard_Boolean hasNodes    = !aNodes.IsEmpty();
+  const Standard_Boolean hasElements = !aElems.IsEmpty();
 
   TColStd_PackedMapOfInteger aNodesToExclude, aElemsToExclude;
-
-  thePresentation->Clear();
-  Standard_Integer len = myBuilders.Length();
-  if ( theMode > 0 )
-    for ( Standard_Integer i=1; i<=len; i++ )
+  for (MeshVS_SequenceOfPrsBuilder::Iterator aBuilderIter (myBuilders); aBuilderIter.More(); aBuilderIter.Next())
+  {
+    const Handle(MeshVS_PrsBuilder)& aBuilder = aBuilderIter.Value();
+    if (!aBuilder.IsNull()
+      && aBuilder->TestFlags (theMode))
     {
-      Handle (MeshVS_PrsBuilder) aCurrent = myBuilders.Value ( i );
-      if ( !aCurrent.IsNull() && aCurrent->TestFlags ( theMode ) )
+      aBuilder->SetPresentationManager (thePrsMgr);
+      if (hasNodes)
       {
-        aCurrent->SetPresentationManager( thePrsMgr );
-        if( HasNodes )
-          aCurrent->Build ( thePresentation, aNodes, aNodesToExclude, Standard_False, theMode );
-        if( HasElements )
-          aCurrent->Build ( thePresentation, aElems, aElemsToExclude, Standard_True,  theMode );
+        aBuilder->Build (thePresentation, aNodes, aNodesToExclude, Standard_False, theMode);
+      }
+      if (hasElements)
+      {
+        aBuilder->Build (thePresentation, aElems, aElemsToExclude, Standard_True,  theMode);
       }
     }
+  }
 
-
-  if ( ShowComputeTime )
+  if (toShowComputeTime)
   {
-    Standard_Real sec, cpu;
-    Standard_Integer min, hour;
-
-    gTimer.Show ( sec, min, hour, cpu );
-    cout << "DisplayMode : " << theMode << endl;
-    cout << "Compute : " << sec << " sec" << endl;
-    cout << "Compute CPU : " << cpu << " sec" << endl << endl;
-    gTimer.Stop();
+    Standard_Real aSec, aCpu;
+    Standard_Integer aMin, anHour;
+    aTimer.Show (aSec, aMin, anHour, aCpu);
+    std::cout << "DisplayMode : " << theMode << "\n";
+    std::cout << "Compute : " << aSec << " sec\n";
+    std::cout << "Compute CPU : " << aCpu << " sec\n\n";
   }
 }
 
index 22e8780..817bed9 100644 (file)
@@ -47,12 +47,14 @@ class MeshVS_Mesh : public AIS_InteractiveObject
 
 public:
 
-  
   //! Constructor.
   //! theIsAllowOverlapped is Standard_True, if it is allowed to draw edges overlapped with beams
   //! Its value is stored in drawer
   Standard_EXPORT MeshVS_Mesh(const Standard_Boolean theIsAllowOverlapped = Standard_False);
-  
+
+  //! Returns true for supported display modes basing on a list of defined builders.
+  Standard_EXPORT virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE;
+
   //! Computes presentation using builders added to sequence. Each builder computes
   //! own part of mesh presentation according to its type.
   Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& PM, const Handle(Prs3d_Presentation)& Prs, const Standard_Integer DisplayMode) Standard_OVERRIDE;