]> OCCT Git - occt-copy.git/commitdiff
0031440: Visualization - Impossible to make common behaviour for multi-selection...
authormzernova <mzernova@opencascade.com>
Tue, 14 Apr 2020 21:54:32 +0000 (00:54 +0300)
committerjfa <jfa@opencascade.com>
Thu, 30 Apr 2020 13:33:31 +0000 (16:33 +0300)
A special mode for the selecting by polygon is added to select only completely overlapping objects.

In order to track the sensitives that were included completely by defined polygon, the boundary points of the polygonal frustrum are stored in the variable myBoundaryPoints.

If an sensitive intersects with at least one of the frustrums from myFrustums, then checking whether this object intersects with borders using the isIntersectBoundary method; if not, then the sensitive were included completely by defined polygon.

Because the polygon can be concave, then to check the sensitive were included completely by defined polygon, it is not enough to check of all its points, it is necessary that the edges of the sensitive do not intersect polygonal frustrum. To do this, for polygonal selection, a call to the Overlaps method for a point was replaced by a call to a segment where necessary.

bugs/vis/bug31440: test case added

14 files changed:
src/AIS/AIS_ViewController.cxx
src/MeshVS/MeshVS_SensitiveQuad.cxx
src/Select3D/Select3D_SensitiveCircle.cxx
src/Select3D/Select3D_SensitivePoly.cxx
src/Select3D/Select3D_SensitiveSegment.cxx
src/Select3D/Select3D_SensitiveTriangle.cxx
src/Select3D/Select3D_SensitiveTriangulation.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx
src/SelectMgr/SelectMgr_TriangularFrustumSet.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/bugs/vis/bug27008
tests/bugs/vis/bug31440 [new file with mode: 0644]

index 0e2ce3a0a9d1445f52cbe163d1c09b353572a85e..afca2141ba0c578d48e68f78b679ead828fc9a65 100644 (file)
@@ -2192,7 +2192,6 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
             aPolyIter.ChangeValue() = gp_Pnt2d (aNewPnt.x(), -aNewPnt.y());
           }
 
-          theCtx->MainSelector()->AllowOverlapDetection (false);
           if (myGL.Selection.IsXOR)
           {
             theCtx->ShiftSelect (aPolyline, theView, false);
@@ -2201,6 +2200,7 @@ void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContex
           {
             theCtx->Select (aPolyline, theView, false);
           }
+          theCtx->MainSelector()->AllowOverlapDetection (false);
         }
       }
 
index 454d9da39cdac04029418a53047a032b4749a08f..e12f3f70ce25a39275b495665fb36ec7ad45740f 100644 (file)
@@ -67,6 +67,12 @@ Standard_Boolean MeshVS_SensitiveQuad::Matches (SelectBasics_SelectingVolumeMana
 {
   if (!theMgr.IsOverlapAllowed()) // check for inclusion
   {
+    if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+    {
+      SelectBasics_PickResult aDummy;
+      return theMgr.Overlaps (myVertices[0], myVertices[1], myVertices[2], Select3D_TOS_INTERIOR, aDummy)
+          && theMgr.Overlaps (myVertices[0], myVertices[2], myVertices[3], Select3D_TOS_INTERIOR, aDummy);
+    }
     for (Standard_Integer aPntIdx = 0; aPntIdx < 4; ++aPntIdx)
     {
       if (!theMgr.Overlaps (myVertices[aPntIdx]))
index e1523f1e4be9e7988b83d93d765f6e9ba66a887d..f2f054e4202266472cfc59670bd881d546e4e796 100644 (file)
@@ -251,6 +251,11 @@ Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolume
     Points3D (anArrayOfPnt);
     if (!theMgr.IsOverlapAllowed())
     {
+      if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+      {
+        SelectBasics_PickResult aDummy;
+        return theMgr.Overlaps (anArrayOfPnt, mySensType, aDummy);
+      }
       for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
       {
         if (!theMgr.Overlaps (anArrayOfPnt->Value(aPntIdx)))
index 61a02bf94bed4a1ecb0f1e02a0d94ab641b090a1..463d2d9533141884a5bffda0ca4731e54c5ddeab 100644 (file)
@@ -254,6 +254,11 @@ Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_Selecting
   }
 
   const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
+  if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+  {
+    SelectBasics_PickResult aDummy;
+    return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0), myPolyg.Pnt3d (aSegmentIdx + 1), aDummy);
+  }
   return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
       && theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
 }
index 9ad66b46b800ec11acfa26eb75f8c53d6e76ec09..4432c6450567850841a4f9b89ba8413a14df5042 100644 (file)
@@ -45,6 +45,10 @@ Standard_Boolean Select3D_SensitiveSegment::Matches (SelectBasics_SelectingVolum
 {
   if (!theMgr.IsOverlapAllowed()) // check for inclusion
   {
+    if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+    {
+      return theMgr.Overlaps (myStart, myEnd, thePickResult);
+    }
     return theMgr.Overlaps (myStart, thePickResult) && theMgr.Overlaps (myEnd, thePickResult);
   }
 
index e5828bc9bc5377af2a54d8382cba4a3542a58941..a2ba6af63653eeaf3a1250b4985524bec368168b 100644 (file)
@@ -50,6 +50,11 @@ Standard_Boolean Select3D_SensitiveTriangle::Matches (SelectBasics_SelectingVolu
 {
   if (!theMgr.IsOverlapAllowed())
   {
+    if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+    {
+      SelectBasics_PickResult aDummy;
+      return theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], mySensType, aDummy);
+    }
     return theMgr.Overlaps (myPoints[0])
         && theMgr.Overlaps (myPoints[1])
         && theMgr.Overlaps (myPoints[2]);
index 859019a73935d0c4f872818db6947bd02b611955..cb79663f8973f0efd6cba0c0ae271990879adc19 100644 (file)
@@ -314,6 +314,11 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
   {
     const gp_Pnt& aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1));
     const gp_Pnt& aSegmPnt2 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 2));
+    if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+    {
+      SelectBasics_PickResult aDummy;
+      return theMgr.Overlaps (aSegmPnt1, aSegmPnt2, aDummy);
+    }
     return theMgr.Overlaps (aSegmPnt1) && theMgr.Overlaps (aSegmPnt2);
   }
   else
@@ -324,6 +329,11 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
     const gp_Pnt& aPnt1 = myTriangul->Nodes().Value (aNode1);
     const gp_Pnt& aPnt2 = myTriangul->Nodes().Value (aNode2);
     const gp_Pnt& aPnt3 = myTriangul->Nodes().Value (aNode3);
+    if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
+    {
+      SelectBasics_PickResult aDummy;
+      return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, mySensType, aDummy);
+    }
     return theMgr.Overlaps (aPnt1)
         && theMgr.Overlaps (aPnt2)
         && theMgr.Overlaps (aPnt3);
index 2ef7b60606271913821f9b39f1c21b8d5ff6566d..8973f9a38d276f267fbbbb50b0fa034a6e45ae7e 100644 (file)
@@ -229,6 +229,7 @@ void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1
     return;
 
   mySelectingVolumes[FrustumSet]->Build (thePoints);
+  Handle(SelectMgr_TriangularFrustumSet)::DownCast (mySelectingVolumes[FrustumSet])->SetAllowOverlapDetection (IsOverlapAllowed());
 }
 
 //=======================================================================
@@ -401,7 +402,7 @@ void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boo
 //=======================================================================
 Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
 {
-  return myActiveSelectionType != Box || myToAllowOverlap;
+  return myToAllowOverlap || myActiveSelectionType == Point;
 }
 
 //=======================================================================
index d0d0ddc67395c93043f5c47bb7d474cbd34f1b5e..63e6defaf4bf4cd9304f35693988071329f1df98 100644 (file)
@@ -158,7 +158,6 @@ public:
   //! Throws exception if active selection type is not Point.
   Standard_EXPORT virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
 
-  //! Is used for rectangular selection only
   //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
   //! mark both included and overlapped entities as matched
   Standard_EXPORT virtual void AllowOverlapDetection (const Standard_Boolean theIsToAllow);
index 7da53986e4d8ace260bda86a89e0dfa53c3dd016..78a5d726542ed0dd95487b4c3399548071115e49 100644 (file)
 
 #define MEMORY_BLOCK_SIZE 512 * 7
 
+// =======================================================================
+// function : SelectMgr_TriangularFrustumSet
+// purpose  :
+// =======================================================================
+SelectMgr_TriangularFrustumSet::SelectMgr_TriangularFrustumSet()
+:  myToAllowOverlap (Standard_False)
+{}
+
 // =======================================================================
 // function : BuildSelectingVolume
 // purpose  : Meshes polygon bounded by polyline. Than organizes a set of
@@ -34,14 +42,20 @@ void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoint
   myFrustums.Clear();
 
   Handle(NCollection_IncAllocator) anAllocator = new NCollection_IncAllocator (MEMORY_BLOCK_SIZE);
-  Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
+  Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun (anAllocator);
   Standard_Integer aPtsLower = thePoints.Lower();
   Standard_Integer aPtsUpper = thePoints.Upper();
   IMeshData::VectorOfInteger anIndexes(aPtsUpper - aPtsLower, anAllocator);
+  myBoundaryPoints.Resize (aPtsLower, aPtsLower + 2 * (thePoints.Size()) - 1, Standard_False);
+
   for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
   {
-    BRepMesh_Vertex aVertex(thePoints.Value(aPtIdx).XY(), aPtIdx, BRepMesh_Frontier);
-    anIndexes.Append(aMeshStructure->AddNode(aVertex));
+    BRepMesh_Vertex aVertex (thePoints.Value (aPtIdx).XY(), aPtIdx, BRepMesh_Frontier);
+    anIndexes.Append (aMeshStructure->AddNode (aVertex));
+    const gp_Pnt aNearPnt = myBuilder->ProjectPntOnViewPlane (aVertex.Coord().X(), aVertex.Coord().Y(), 0.0);
+    const gp_Pnt aFarPnt  = myBuilder->ProjectPntOnViewPlane (aVertex.Coord().X(), aVertex.Coord().Y(), 1.0);
+    myBoundaryPoints.SetValue (aPtIdx, aNearPnt);
+    myBoundaryPoints.SetValue (aPtIdx + thePoints.Size(), aFarPnt);
   }
 
   Standard_Real aPtSum = 0;
@@ -118,6 +132,14 @@ Handle(SelectMgr_BaseFrustum) SelectMgr_TriangularFrustumSet::ScaleAndTransform
     aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->ScaleAndTransform (theScale, theTrsf)));
   }
 
+  aRes->myBoundaryPoints.Resize (myBoundaryPoints.Lower(), myBoundaryPoints.Upper(), Standard_False);
+  for (Standard_Integer anIdx = myBoundaryPoints.Lower(); anIdx <= myBoundaryPoints.Upper(); anIdx++)
+  {
+    gp_Pnt aPoint = myBoundaryPoints.Value (anIdx);
+    theTrsf.Transforms (aPoint.ChangeCoord());
+    aRes->myBoundaryPoints.SetValue (anIdx, aPoint);
+  }
+
   return aRes;
 }
 
@@ -145,12 +167,43 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3&
 // =======================================================================
 Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3& theMinPnt,
                                                            const SelectMgr_Vec3& theMaxPnt,
-                                                           Standard_Boolean* /*theInside*/) const
+                                                           Standard_Boolean* theInside) const
 {
   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
   {
     if (anIter.Value()->Overlaps (theMinPnt, theMaxPnt, NULL))
-      return Standard_True;
+    {
+      if (myToAllowOverlap || theInside == NULL)
+      {
+        return Standard_True;
+      }
+      else
+      {
+        gp_Pnt aMinMaxPnts[2] = { gp_Pnt (theMinPnt.x(), theMinPnt.y(), theMinPnt.z()),
+                                  gp_Pnt (theMaxPnt.x(), theMaxPnt.y(), theMaxPnt.z())};
+
+        gp_Pnt anOffset[3] = { gp_Pnt (aMinMaxPnts[1].X() - aMinMaxPnts[0].X(), 0.0, 0.0),
+                               gp_Pnt (0.0, aMinMaxPnts[1].Y() - aMinMaxPnts[0].Y(), 0.0),
+                               gp_Pnt (0.0, 0.0, aMinMaxPnts[1].Z() - aMinMaxPnts[0].Z()) };
+
+        Standard_Integer aSign = 1;
+        for (Standard_Integer aPntsIdx = 0; aPntsIdx < 2; aPntsIdx++)
+        {
+          for (Standard_Integer aCoordIdx = 0; aCoordIdx < 3; aCoordIdx++)
+          {
+            gp_Pnt anOffsetPnt = aMinMaxPnts [aPntsIdx].XYZ() + aSign * anOffset [aCoordIdx].XYZ();
+            if (isIntersectBoundary (aMinMaxPnts [aPntsIdx], anOffsetPnt)
+             || isIntersectBoundary (anOffsetPnt, anOffsetPnt.XYZ() + aSign * anOffset [(aCoordIdx + 1) % 3].XYZ()))
+            {
+              *theInside &= Standard_False;
+              return Standard_True;
+            }
+          }
+          aSign = -aSign;
+        }
+        return Standard_True;
+      }
+    }
   }
 
   return Standard_False;
@@ -185,7 +238,25 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const TColgp_Array1Of
   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
   {
     if (anIter.Value()->Overlaps (theArrayOfPts, theSensType, theClipRange, thePickResult))
-      return Standard_True;
+    {
+      if (myToAllowOverlap)
+      {
+        return Standard_True;
+      }
+      else
+      {
+        Standard_Integer aPtsLower = theArrayOfPts.Lower();
+        Standard_Integer aPtsUpper = theArrayOfPts.Upper();
+        for (Standard_Integer anIdx = aPtsLower; anIdx <= aPtsUpper; anIdx++)
+        {
+          if (isIntersectBoundary (theArrayOfPts.Value (anIdx), theArrayOfPts.Value (anIdx < aPtsUpper ? anIdx + 1 : aPtsLower)))
+          {
+            return Standard_False;
+          }
+        }
+        return Standard_True;
+      }
+    }
   }
 
   return Standard_False;
@@ -203,7 +274,20 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1
   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
   {
     if (anIter.Value()->Overlaps (thePnt1, thePnt2, theClipRange, thePickResult))
-      return Standard_True;
+    {
+      if (myToAllowOverlap)
+      {
+        return Standard_True;
+      }
+      else
+      {
+        if (isIntersectBoundary (thePnt1, thePnt2))
+        {
+          return Standard_False;
+        }
+        return Standard_True;
+      }
+    }
   }
 
   return Standard_False;
@@ -223,7 +307,22 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const gp_Pnt& thePnt1
   for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
   {
     if (anIter.Value()->Overlaps (thePnt1, thePnt2, thePnt3, theSensType, theClipRange, thePickResult))
-      return Standard_True;
+    {
+      if (myToAllowOverlap)
+      {
+        return Standard_True;
+      }
+      else
+      {
+        if (isIntersectBoundary (thePnt1, thePnt2)
+         || isIntersectBoundary (thePnt2, thePnt3)
+         || isIntersectBoundary (thePnt3, thePnt1))
+        {
+          return Standard_False;
+        }
+        return Standard_True;
+      }
+    }
   }
 
   return Standard_False;
@@ -243,4 +342,83 @@ void SelectMgr_TriangularFrustumSet::GetPlanes (NCollection_Vector<SelectMgr_Vec
   }
 }
 
+//=======================================================================
+// function : SetAllowOverlapDetection
+// purpose  :
+//=======================================================================
+void SelectMgr_TriangularFrustumSet::SetAllowOverlapDetection (const Standard_Boolean theIsToAllow)
+{
+  myToAllowOverlap = theIsToAllow;
+}
+
+//=======================================================================
+// function : isIntersectBoundary
+// purpose  :
+//=======================================================================
+Standard_Boolean SelectMgr_TriangularFrustumSet::isIntersectBoundary (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2) const
+{
+  Standard_Integer aFacesNb = myBoundaryPoints.Size() / 2;
+  gp_Vec aDir = thePnt2.XYZ() - thePnt1.XYZ();
+  gp_Pnt anOrig = thePnt1;
+
+  for (Standard_Integer anIdx = myBoundaryPoints.Lower(); anIdx < aFacesNb + myBoundaryPoints.Lower(); anIdx++)
+  {
+    gp_Pnt aFace[4] = { myBoundaryPoints.Value (anIdx),
+                        myBoundaryPoints.Value (anIdx + aFacesNb),
+                        myBoundaryPoints.Value (anIdx % aFacesNb + 1 + aFacesNb),
+                        myBoundaryPoints.Value (anIdx % aFacesNb + 1) };
+
+    if (segmentTriangleIntersection (anOrig, aDir, aFace[0], aFace[1], aFace[2])
+     || segmentTriangleIntersection (anOrig, aDir, aFace[0], aFace[2], aFace[3]))
+    {
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+// function : segmentTriangleIntersection
+// purpose  : Moller-Trumbore ray-triangle intersection test
+//=======================================================================
+Standard_Boolean SelectMgr_TriangularFrustumSet::segmentTriangleIntersection (const gp_Pnt& theOrig, const gp_Vec& theDir,
+                                                                              const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3) const
+{
+  gp_Vec        aPVec, aTVec, aQVec;
+  Standard_Real aD, aInvD, anU, aV, aT;
+
+  gp_Vec anEdge1 = theV2.XYZ() - theV1.XYZ();
+  gp_Vec anEdge2 = theV3.XYZ() - theV1.XYZ();
+
+  aPVec = theDir.Crossed (anEdge2);
+  aD = anEdge1.Dot (aPVec);
+  if (fabs (aD) < gp::Resolution())
+  {
+    return Standard_False;
+  }
+
+  aInvD = 1.0 / aD;
+  aTVec = theOrig.XYZ() - theV1.XYZ();
+  anU = aInvD * aTVec.Dot (aPVec);
+  if (anU < 0.0 || anU > 1.0)
+  {
+    return Standard_False;
+  }
+
+  aQVec = aTVec.Crossed (anEdge1);
+  aV = aInvD * theDir.Dot (aQVec);
+  if (aV < 0.0 || anU + aV > 1.0)
+  {
+    return Standard_False;
+  }
+
+  aT = aInvD * anEdge2.Dot (aQVec);
+  if (aT < 0 || aT > 1)
+  {
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
+
 #undef MEMORY_BLOCK_SIZE
index fc2d4c122c647d3f40ead5cf505a82d69166dc2f..08f4cb5b01f44e1cad7aabd5521799c7bfa24232 100644 (file)
@@ -37,7 +37,7 @@ class SelectMgr_TriangularFrustumSet : public SelectMgr_BaseFrustum
 {
 public:
 
-  SelectMgr_TriangularFrustumSet() {};
+  SelectMgr_TriangularFrustumSet();
 
   ~SelectMgr_TriangularFrustumSet() {};
 
@@ -84,9 +84,24 @@ public:
   //! Ax + By + Cz + D = 0) to the given vector
   Standard_EXPORT virtual void GetPlanes (NCollection_Vector<SelectMgr_Vec4>& thePlaneEquations) const Standard_OVERRIDE;
 
+  //! If theIsToAllow is false, only fully included sensitives will be detected, otherwise the algorithm will
+  //! mark both included and overlapped entities as matched
+  Standard_EXPORT virtual void SetAllowOverlapDetection (const Standard_Boolean theIsToAllow);
+
+private:
+
+  //! Checks whether the segment intersects with the boundary of the current volume selection
+  Standard_EXPORT Standard_Boolean isIntersectBoundary (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2) const;
+
+  //! Checks whether the triangle intersects with a segment
+  Standard_EXPORT Standard_Boolean segmentTriangleIntersection (const gp_Pnt &theOrig, const gp_Vec& theDir,
+                                                                const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3) const;
+
 private:
 
-    SelectMgr_TriangFrustums myFrustums;
+  SelectMgr_TriangFrustums myFrustums;
+  TColgp_Array1OfPnt       myBoundaryPoints;
+  Standard_Boolean         myToAllowOverlap;
 };
 
 #endif // _SelectMgr_TriangularFrustumSet_HeaderFile
index 336ecbd3317b0fdf869c5c31ff0973b8d63401b6..f548f505b2ec08ec21825b494492a4d3971c477c 100644 (file)
@@ -7575,12 +7575,7 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
       return 1;
     }
   }
-  if (toAllowOverlap
-   && aPnts.Length() != 2)
-  {
-    std::cout << "Syntax error: -allowoverlap key is applied only for rectangle selection\n";
-    return 1;
-  }
+
   if (toAllowOverlap)
   {
     aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
@@ -13933,10 +13928,10 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "- 1) single click selection\n"
     "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
     "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
-    "- 4) -allowoverlap manages overlap and inclusion detection in rectangular selection.\n"
-    "     If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined rectangle will be detected,\n"
-    "     otherwise algorithm will chose only fully included sensitives. Default behavior is to detect only full inclusion. "
-    " (partial inclusion - overlap - is not allowed by default)\n"
+    "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
+    "     If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
+    "     rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
+    "     Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
     "- 5) any of these selections with shift button pressed",
     __FILE__, VSelect, group);
   theCommands.Add ("vmoveto",
index 24a6bfdcf43d3e78223dd95bdc89013168c27878..6a326d51f7ca93f43603ca7c1fa9a9404ea2f532 100644 (file)
@@ -15,7 +15,7 @@ vsetdispmode m 2
 
 vselmode m 8 1
 vselect 0 0 409 409 0 409
-if { [vnbselected] != "56748" } { puts "Error: the number of selected elements differs for mode 8" }
+if { [vnbselected] != "55607" } { puts "Error: the number of selected elements differs for mode 8" }
 vdump $imagedir/${casename}_mode_8.png
 
 vselect 0 0
diff --git a/tests/bugs/vis/bug31440 b/tests/bugs/vis/bug31440
new file mode 100644 (file)
index 0000000..1d6a897
--- /dev/null
@@ -0,0 +1,34 @@
+puts "============"
+puts "0031440: Visualization - Impossible to make common behaviour for multi-selection in viewer"
+puts "============"
+puts ""
+
+vinit View1
+vpoint radP1 0 0 0
+vpoint radP2 50 50 0
+vpoint radP3 100 0 0
+vcircle circle radP1 radP2 radP3 1
+vfit
+
+vselect 50 300 150 300 150 100 50 100
+if {[vreadpixel 120 200 rgb name] != "DARKGOLDENROD"} { puts "ERROR: the circle is selected with no overlap mode activated" }
+vselect 0 0
+
+vselect 50 300 360 300 360 100 50 100
+if {[vreadpixel 120 200 rgb name] != "GRAY73"} { puts "ERROR: the circle is not selected" }
+vselect 0 0
+vclear
+
+box b 0 0 0 1 1 1
+vdisplay b 
+vfit
+vselmode b 2 1
+vviewparams -scale 500
+
+vdrawparray line polylines v 10 9 0 v 400 9 0 v 400 209 0 v 200 109 0 v 10 209 0 v 10 9 0
+vdisplay line -2d
+vsetcolor line red
+
+vselect 10 400 400 400 400 200 200 300 10 200
+
+vdump ${imagedir}/${casename}.png