diff --git a/src/Select3D/Select3D_SensitiveCurve.cdl b/src/Select3D/Select3D_SensitiveCurve.cdl index 5c4c2971d6..c5ddfedaf7 100644 --- a/src/Select3D/Select3D_SensitiveCurve.cdl +++ b/src/Select3D/Select3D_SensitiveCurve.cdl @@ -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 and + -- the eye-line . + returns Boolean from Standard + is protected; + fields mylastseg : Integer from Standard; myCurve : Curve from Geom; diff --git a/src/Select3D/Select3D_SensitiveCurve.cxx b/src/Select3D/Select3D_SensitiveCurve.cxx index 5953810292..9c3144681f 100644 --- a/src/Select3D/Select3D_SensitiveCurve.cxx +++ b/src/Select3D/Select3D_SensitiveCurve.cxx @@ -20,7 +20,7 @@ #include #include #include - +#include //================================================== // 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 and +// the eye-line . +//======================================================================= + +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; +} diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cdl b/src/SelectMgr/SelectMgr_ViewerSelector.cdl index 1348a26a71..01143d4135 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cdl +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cdl @@ -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; diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index 4d29cdf016..31210be3d2 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -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()) { diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.lxx b/src/SelectMgr/SelectMgr_ViewerSelector.lxx index d43f3d4ed6..2872a3ac38 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.lxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.lxx @@ -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 { diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 210a3d0d75..804b3f9258 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -57,6 +57,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -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 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 index 0000000000..60b59351d7 --- /dev/null +++ b/tests/bugs/vis/bug25098 @@ -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" +} diff --git a/tests/v3d/wire_solid/C7 b/tests/v3d/wire_solid/C7 index f16e5cf016..0bd8ed50ff 100644 --- a/tests/v3d/wire_solid/C7 +++ b/tests/v3d/wire_solid/C7 @@ -26,5 +26,5 @@ vmoveto 100 329 vmoveto 0 0 vmoveto 200 245 vmoveto 0 0 -vmoveto 300 349 +vmoveto 300 345 diff --git a/tests/v3d/wire_solid/D5 b/tests/v3d/wire_solid/D5 index 99a3ef4df7..1680cccbac 100644 --- a/tests/v3d/wire_solid/D5 +++ b/tests/v3d/wire_solid/D5 @@ -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 diff --git a/tests/v3d/wire_solid/E7 b/tests/v3d/wire_solid/E7 index 675d890b1d..43afe2e59b 100644 --- a/tests/v3d/wire_solid/E7 +++ b/tests/v3d/wire_solid/E7 @@ -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 diff --git a/tests/v3d/wire_solid/F1 b/tests/v3d/wire_solid/F1 index 83234237af..4136dbe2d9 100644 --- a/tests/v3d/wire_solid/F1 +++ b/tests/v3d/wire_solid/F1 @@ -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 diff --git a/tests/v3d/wire_solid/H9 b/tests/v3d/wire_solid/H9 index 4a320bab93..a8666cc057 100644 --- a/tests/v3d/wire_solid/H9 +++ b/tests/v3d/wire_solid/H9 @@ -28,5 +28,5 @@ vmoveto 100 329 vmoveto 0 0 vmoveto 200 245 vmoveto 0 0 -vmoveto 300 349 +vmoveto 300 345 diff --git a/tests/v3d/wire_solid/I7 b/tests/v3d/wire_solid/I7 index 103b7dae54..20cf129c8f 100644 --- a/tests/v3d/wire_solid/I7 +++ b/tests/v3d/wire_solid/I7 @@ -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 diff --git a/tests/v3d/wire_solid/K3 b/tests/v3d/wire_solid/K3 index 6fbe703b9c..d568745431 100644 --- a/tests/v3d/wire_solid/K3 +++ b/tests/v3d/wire_solid/K3 @@ -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