]> 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)
committerbugmaster <bugmaster@opencascade.com>
Thu, 23 Apr 2020 07:44:30 +0000 (10:44 +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 87a4864bc7e3b6f51a556cf62071f7c7d2763ee7..d4e79f7a48e9106ef2f45b680fc22ab68ed91489 100644 (file)
@@ -2210,7 +2210,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);
@@ -2219,6 +2218,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 3f3f14f5c2d2f360221697b21722e44251f96019..82bf115bdecefa14d8dcfe1c7f33014b2dbaa162 100644 (file)
@@ -211,6 +211,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 bca131d68594aed5977d22796c504f2b19fd330f..d582fef161e31afb01d8c3a5b0f35574da122a29 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 520741138b3262e33a9863084b8ccbd66ec95903..c402199ce984befde8bc2f598e3d369e842aaa11 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 2b14690632edb6b7f15d652385584e8cb798632f..47291ad68a673befef117c89a3a2488038e32aed 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 e80dbc64704b54da4371e7dad3f18b89e10e44b4..ad7677011be3ef2ac70dbd885ec919f007e0c7f3 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 03cbffa88f1517b4d3934add82f78e34887c775e..89230c7668df04a78e34060c7cf0f901d44204e4 100644 (file)
@@ -230,6 +230,7 @@ void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1
     return;
 
   mySelectingVolumes[FrustumSet]->Build (thePoints);
+  Handle(SelectMgr_TriangularFrustumSet)::DownCast (mySelectingVolumes[FrustumSet])->SetAllowOverlapDetection (IsOverlapAllowed());
 }
 
 //=======================================================================
@@ -402,7 +403,7 @@ void SelectMgr_SelectingVolumeManager::AllowOverlapDetection (const Standard_Boo
 //=======================================================================
 Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
 {
-  return myActiveSelectionType != Box || myToAllowOverlap;
+  return myToAllowOverlap || myActiveSelectionType == Point;
 }
 
 //=======================================================================
index 5b89bbdd921a3c95e08448f073f11639456bd75a..6b3fe7822db8179213e2049f3c7bb6c92bb508d6 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 9bc02b1375edb165777901dbf4a23b4ae27d0b95..3ac07336efc1b3034b54cfdabee9cc11cfdd1df1 100644 (file)
@@ -7635,12 +7635,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);
@@ -14279,10 +14274,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