0025098: Visualization, Select3D_SensitiveCurve - fix computation of the depth
authorvro <vro@opencascade.com>
Fri, 12 Sep 2014 11:11:53 +0000 (15:11 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 2 Oct 2014 09:50:03 +0000 (13:50 +0400)
Draw Harness, add option -entities to command vstate.
Within new option command displays information about detection entities.

14 files changed:
src/Select3D/Select3D_SensitiveCurve.cdl
src/Select3D/Select3D_SensitiveCurve.cxx
src/SelectMgr/SelectMgr_ViewerSelector.cdl
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/SelectMgr/SelectMgr_ViewerSelector.lxx
src/ViewerTest/ViewerTest.cxx
tests/bugs/vis/bug25098 [new file with mode: 0644]
tests/v3d/wire_solid/C7
tests/v3d/wire_solid/D5
tests/v3d/wire_solid/E7
tests/v3d/wire_solid/F1
tests/v3d/wire_solid/H9
tests/v3d/wire_solid/I7
tests/v3d/wire_solid/K3

index 5c4c297..c5ddfed 100644 (file)
@@ -36,10 +36,11 @@ uses
     Curve           from Geom,
     Array1OfPnt     from TColgp,
     Array1OfPnt2d   from TColgp,
-    HArray1OfPnt     from TColgp,
+    HArray1OfPnt    from TColgp,
     Box2d           from Bnd,
-    Location                 from TopLoc, 
-    SensitiveEntity   from Select3D
+    Location        from TopLoc,
+    SensitiveEntity from Select3D,
+    XYZ             from gp
 
 raises
     ConstructionError from Standard,
@@ -120,6 +121,17 @@ is
         ---Level: Public 
         ---Purpose: Returns the copy of this
 
+    ComputeDepth(me;
+                 thePickLine : Lin from gp;
+                 theP1       : XYZ from gp;
+                 theP2       : XYZ from gp;
+                 theDepth    : out Real from Standard)
+    ---Purpose: Computes the depth by means of intersection of
+    --          a segment of the curve defined by <theP1, theP2> and
+    --          the eye-line <thePickLine>.
+    returns Boolean from Standard
+    is protected;
+
 fields
     mylastseg : Integer        from Standard;
     myCurve  : Curve from Geom;
index 5953810..9c31446 100644 (file)
@@ -20,7 +20,7 @@
 #include <Precision.hxx>
 #include <ElCLib.hxx>
 #include <CSLib_Class2d.hxx>
-
+#include <Extrema_ExtElC.hxx>
 
 //==================================================
 // Function: Creation
@@ -187,20 +187,43 @@ void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean Fu
 Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
                                                      const Standard_Integer theSegment) const
 {
+  Standard_Real aDepth = Precision::Infinite();
   if (theSegment == 0)
   {
-    return Precision::Infinite();
+    return aDepth;
   }
 
   // In case if theSegment and theSegment + 1 are not valid
   // the depth will be infinite
   if (theSegment >= mypolyg.Size())
   {
-    return Precision::Infinite();
+    return aDepth;
   }
 
   gp_XYZ aCDG = mypolyg.Pnt (theSegment);
 
+  // Check depth of a line forward within the curve.
+  if (theSegment + 1 < mypolyg.Size())
+  {
+    gp_XYZ aCDG1 = mypolyg.Pnt (theSegment + 1);
+    if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth))
+    {
+      return aDepth;
+    }
+  }
+
+  // Check depth of a line backward within the curve.
+  if (theSegment - 1 >= 0)
+  {
+    gp_XYZ aCDG1 = mypolyg.Pnt (theSegment - 1);
+    if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth))
+    {
+      return aDepth;
+    }
+  }
+
+  // Calculate the depth in the middle point of
+  // a next (forward) segment of the curve.
   if (theSegment + 1 < mypolyg.Size())
   {
     aCDG += mypolyg.Pnt(theSegment + 1);
@@ -244,3 +267,48 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected(const Top
 
   return aNewEntity;
 }
+
+//=======================================================================
+//function : ComputeDepth()
+//purpose  : Computes the depth by means of intersection of
+//           a segment of the curve defined by <theP1, theP2> and
+//           the eye-line <thePickLine>.
+//=======================================================================
+
+Standard_Boolean Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& thePickLine,
+                                                       const gp_XYZ& theP1,
+                                                       const gp_XYZ& theP2,
+                                                       Standard_Real& theDepth) const
+{
+  // The segment may have null length.
+  gp_XYZ aVec = theP2 - theP1;
+  Standard_Real aLength = aVec.Modulus();
+  if (aLength <= gp::Resolution())
+  {
+    theDepth = ElCLib::Parameter(thePickLine, theP1);
+    return Standard_True;
+  }
+
+  // Compute an intersection point of the segment-line and the eye-line.
+  gp_Lin aLine (theP1, aVec);
+  Extrema_ExtElC anExtrema(aLine, thePickLine, Precision::Angular());
+  if (anExtrema.IsDone() && !anExtrema.IsParallel() )
+  {
+    // Iterator on solutions (intersection points).
+    for (Standard_Integer i = 1; i <= anExtrema.NbExt(); i++)
+    {
+      // Get the intersection point.
+      Extrema_POnCurv aPointOnLine1, aPointOnLine2;
+      anExtrema.Points(i, aPointOnLine1, aPointOnLine2);
+
+      // Check bounds: the point of intersection should lie within the segment.
+      if (aPointOnLine1.Parameter() > 0.0 && aPointOnLine1.Parameter() < aLength)
+      {
+        theDepth = ElCLib::Parameter(thePickLine, aPointOnLine1.Value());
+        return Standard_True;
+      }
+    }
+  }
+
+  return Standard_False;
+}
index 1348a26..01143d4 100644 (file)
@@ -71,6 +71,7 @@ uses
     IndexedDataMapOfOwnerCriterion   from SelectMgr,
     SensitiveEntity              from SelectBasics,
     SortAlgo                     from SelectBasics,
+    PickArgs                     from SelectBasics,
     EntityOwner                  from SelectMgr,
     StateOfSelection             from SelectMgr,
     Array1OfPnt2d                from TColgp,
@@ -396,6 +397,11 @@ is
     -- @param theOwner [in] the onwer to check.
     -- @return True if owner provides depth limits for sensitive clipping.
 
+    LastPickingArguments(me) returns PickArgs from SelectBasics;
+    ---C++: inline
+    ---C++: return const&
+    -- Return last picking arguments.
+
 fields
 
 --before selection
@@ -415,6 +421,7 @@ fields
     myprim       : SequenceOfInteger from TColStd; -- for debug only
     myCurRank    : Integer from Standard;
 
+    myLastPickArgs : PickArgs from SelectBasics;
     lastx        : Real;
     lasty        : Real;
 
index 4d29cdf..31210be 100644 (file)
@@ -86,6 +86,7 @@ tosort(Standard_True),
 preferclosest(Standard_True),
 mytolerance(0.),
 myCurRank(0),
+myLastPickArgs (0.0, 0.0, 0.0, RealFirst(), RealLast(), gp_Lin()),
 lastx (Precision::Infinite()),
 lasty (Precision::Infinite()),
 myUpdateSortPossible( Standard_True )
@@ -479,12 +480,12 @@ void SelectMgr_ViewerSelector::LoadResult()
           continue;
         }
 
-        SelectBasics_PickArgs aPickArgs (lastx, lasty, mytolerance,
-                                         anEntityDRange.DepthMin,
-                                         anEntityDRange.DepthMax,
-                                         aPickLine);
+        myLastPickArgs = SelectBasics_PickArgs (lastx, lasty, mytolerance,
+                                                anEntityDRange.DepthMin,
+                                                anEntityDRange.DepthMax,
+                                                aPickLine);
 
-        if (SE->Matches (aPickArgs, aDMin, aDepthMin))
+        if (SE->Matches (myLastPickArgs, aDMin, aDepthMin))
         {
           if (!anOwner.IsNull())
           {
index d43f3d4..2872a3a 100644 (file)
@@ -35,6 +35,11 @@ inline void SelectMgr_ViewerSelector::SetPickClosest (const Standard_Boolean pre
   preferclosest = preferClosest;
 }
 
+inline const SelectBasics_PickArgs& SelectMgr_ViewerSelector::LastPickingArguments() const
+{
+  return myLastPickArgs;
+}
+
 #ifdef OCC9026
 inline const SelectMgr_DataMapOfIntegerSensitive& SelectMgr_ViewerSelector::Primitives() const
 {
index 210a3d0..804b3f9 100644 (file)
 #include <Image_AlienPixMap.hxx>
 #include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_IsoAspect.hxx>
+#include <Select3D_SensitiveWire.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <StdSelect_BRepOwner.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
+#include <Select3D_Projector.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <ViewerTest_AutoUpdater.hxx>
 
@@ -3459,7 +3464,6 @@ static void localCtxInfo (Draw_Interpretor& theDI)
 //==============================================================================
 //function : VState
 //purpose  :
-//Draw arg : vstate [nameA] ... [nameN]
 //==============================================================================
 static Standard_Integer VState (Draw_Interpretor& theDI,
                                 Standard_Integer  theArgNb,
@@ -3472,6 +3476,55 @@ static Standard_Integer VState (Draw_Interpretor& theDI,
     return 1;
   }
 
+  TCollection_AsciiString anOption (theArgNb >= 2 ? theArgVec[1] : "");
+  anOption.LowerCase();
+  if (anOption == "-detectedEntities"
+   || anOption == "-entities")
+  {
+    theDI << "Detected entities:\n";
+    Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->HasOpenedContext() ? aCtx->LocalSelector() : aCtx->MainSelector();
+    for (aSelector->Init(); aSelector->More(); aSelector->Next())
+    {
+      Handle(SelectBasics_SensitiveEntity) anEntity = aSelector->Primitive (0);
+      Standard_Real aMatchDMin  = 0.0;
+      Standard_Real aMatchDepth = Precision::Infinite();
+      anEntity->Matches (aSelector->LastPickingArguments(), aMatchDMin, aMatchDepth);
+
+      Handle(SelectMgr_EntityOwner) anOwner    = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
+      Handle(AIS_InteractiveObject) anObj      = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
+
+      const gp_Lin aLine = aSelector->LastPickingArguments().PickLine();
+      const gp_Pnt aPnt  = aLine.Location().Translated (gp_Vec (aLine.Direction()) * aMatchDepth);
+
+      TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
+      aName.LeftJustify (20, ' ');
+      char anInfoStr[512];
+      Sprintf (anInfoStr, " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f", aMatchDepth, aMatchDMin, aPnt.X(), aPnt.Y(), aPnt.Z());
+      theDI << "  " << aName
+            << anInfoStr
+            << " (" << anEntity->DynamicType()->Name() << ")"
+            << "\n";
+
+      Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
+      if (!aBRepOwner.IsNull())
+      {
+        theDI << "                       Detected Shape: "
+              << aBRepOwner->Shape().TShape()->DynamicType()->Name()
+              << "\n";
+      }
+
+      Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast (anEntity);
+      if (!aWire.IsNull())
+      {
+        Handle(Select3D_SensitiveEntity) aSen = aWire->GetLastDetected();
+        theDI << "                       Detected Child: "
+              << aSen->DynamicType()->Name()
+              << "\n";
+      }
+    }
+    return 0;
+  }
+
   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
   {
@@ -4382,8 +4435,9 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
                  __FILE__,VActivatedMode,group);
 
   theCommands.Add("vstate",
-      "vstate [name1] ... [nameN]"
-      "\n\t\t: Reports show/hidden state for selected or named objects",
+      "vstate [-entities] [name1] ... [nameN]"
+      "\n\t\t: Reports show/hidden state for selected or named objects"
+      "\n\t\t:   -entities - print low-level information about detected entities",
                  __FILE__,VState,group);
 
   theCommands.Add("vpickshapes",
diff --git a/tests/bugs/vis/bug25098 b/tests/bugs/vis/bug25098
new file mode 100644 (file)
index 0000000..60b5935
--- /dev/null
@@ -0,0 +1,115 @@
+puts "============"
+puts "OCC25098"
+puts "============"
+puts ""
+####################################################################################
+# Visualization - Calculation of depth on selection of a wire is not accurate
+####################################################################################
+
+proc ParseEntityInfo {theInfoString} {
+  set aStringArr [split $theInfoString " "]
+  set aDepth ""
+  set aDistance ""
+  set aPoint ""
+  set aType ""
+  set aSize [llength $aStringArr]
+  for {set aIdx 0} {$aIdx < $aSize} {incr aIdx} {
+    set aItem [lindex $theInfoString $aIdx]
+    if {[string compare $aItem "Depth:"] == 0} {
+      set aDepth [string trim [lindex $theInfoString [expr $aIdx + 1]]]
+    } elseif {[string compare $aItem "Distance:"] == 0} {
+        set aDistance [string trim [lindex $theInfoString [expr $aIdx + 1]]]
+    } elseif {[string compare $aItem "Point:"] == 0} {
+        set aPoint [string trim [lindex $theInfoString [expr $aIdx + 1]]]
+        append aPoint " "
+        append aPoint [string trim [lindex $theInfoString [expr $aIdx + 2]]]
+        append aPoint " "
+        append aPoint [string trim [lindex $theInfoString [expr $aIdx + 3]]]
+      } elseif {[string compare [string index $aItem 0] "("] == 0} {
+        set aType [string trim $aItem]
+    }
+  }
+
+  return [list $aDepth $aDistance $aPoint $aType]
+}
+
+pload VISUALIZATION MODELING
+vinit
+
+box b 10 10 10
+vdisplay b
+vremove b
+
+explode b w
+vdisplay b_5
+
+vertex v1 10 0 0
+vertex v2 10 10 0
+edge e v1 v2
+vdisplay e
+
+vfit
+vmoveto 240 300
+set aOut [split [vstate -entities] "\n"]
+
+# compare parameters of detected match: depth, distance and point
+set aEdgeInfoList [ParseEntityInfo [lindex $aOut 1]]
+set aWireInfoList [ParseEntityInfo [lindex $aOut 3]]
+for {set aIdx 0} {$aIdx < 3} {incr aIdx} {
+  if {[string equal [lindex $aEdgeInfoList $aIdx] [lindex $aWireInfoList $aIdx]] == 0} {
+    set aDebugInfo "Characteristics are not equal at value nb: "
+    append aDebugInfo [expr $aIdx + 1]
+    puts $aDebugInfo
+    set aDebugInfo "The values are: "
+    append aDebugInfo [lindex $aEdgeInfoList $aIdx]
+    append aDebugInfo " and "
+    append aDebugInfo [lindex $aWireInfoList $aIdx]
+    puts $aDebugInfo
+    puts "ERROR"
+    puts ""
+  }
+}
+
+# checks that edge e is represented by correct shape and sensitive entity
+if {[string equal [lindex $aEdgeInfoList 3] "(Select3D_SensitiveSegment)"] == 0} {
+  puts "Wrong sensitive for segment! Value is: "
+  puts [lindex $aEdgeInfoList 3]
+  puts "Must be: (Select3D_SensitiveSegment)"
+  puts "ERROR"
+  puts ""
+}
+
+set aEdgeType [string trim [lindex $aOut 2]]
+if {[string equal $aEdgeType "Detected Shape: BRep_TEdge"] == 0} {
+  puts "Wrong type of edge! Value is: "
+  puts $aEdgeType
+  puts "Must be: Detected Shape: BRep_TEdge"
+  puts "ERROR"
+  puts ""
+}
+
+# checks that wire b_5 is represented by correct shape and sensitive entity
+if {[string equal [lindex $aWireInfoList 3] "(Select3D_SensitiveWire)"] == 0} {
+  puts "Wrong sensitive for wire! Value is: "
+  puts [lindex $aWireInfoList 3]
+  puts "Must be: (Select3D_SensitiveWire)"
+  puts "ERROR"
+  puts ""
+}
+
+set aWireType [string trim [lindex $aOut 4]]
+if {[string equal $aWireType "Detected Shape: TopoDS_TWire"] == 0} {
+  puts "Wrong type of wire! Value is: "
+  puts $aWireType
+  puts "Must be: Detected Shape: TopoDS_TWire"
+  puts "ERROR"
+  puts ""
+}
+
+set aWireSensitiveType [string trim [lindex $aOut 5]]
+if {[string equal $aWireSensitiveType "Detected Child: Select3D_SensitiveCurve"] == 0} {
+  puts "Wrong type of wire's inner sensitive! Value is: "
+  puts $aWireSensitiveType
+  puts "Must be: Detected Child: Select3D_SensitiveCurve"
+  puts "ERROR"
+}
index f16e5cf..0bd8ed5 100644 (file)
@@ -26,5 +26,5 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 
index 99a3ef4..1680ccc 100644 (file)
@@ -26,7 +26,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vselect 100 329 1
 vmoveto 0 0
@@ -34,5 +34,5 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 
index 675d890..43afe2e 100644 (file)
@@ -26,7 +26,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vselect 100 329 1
 vmoveto 0 0
@@ -34,7 +34,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vviewparams -scale 6.063093 -proj 0.524772 0.731256 0.434393 -up 0.716008 -0.104342 -0.691426 -at 21.6212460112894 0.5192504580656 16.591446657356
 vfit
index 8323423..4136dbe 100644 (file)
@@ -26,7 +26,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vselect 100 329 1
 vmoveto 0 0
@@ -34,7 +34,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vviewparams -scale 6.063093 -proj 0.524772 0.731256 0.434393 -up 0.716008 -0.104342 -0.691426 -at 21.6212460112894 0.5192504580656 16.591446657356
 vfit
index 4a320ba..a8666cc 100644 (file)
@@ -28,5 +28,5 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 
index 103b7da..20cf129 100644 (file)
@@ -28,7 +28,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vselect 100 329 1
 vmoveto 0 0
@@ -36,5 +36,5 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 
index 6fbe703..d568745 100644 (file)
@@ -28,7 +28,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vselect 100 329 1
 vmoveto 0 0
@@ -36,7 +36,7 @@ vmoveto 100 329
 vmoveto 0 0
 vmoveto 200 245
 vmoveto 0 0
-vmoveto 300 349
+vmoveto 300 345
 vmoveto 0 0
 vviewparams -scale 6.063093 -proj 0.524772 0.731256 0.434393 -up 0.716008 -0.104342 -0.691426 -at 21.6212460112894 0.5192504580656 16.591446657356
 vfit