mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0025098: Visualization, Select3D_SensitiveCurve - fix computation of the depth
Draw Harness, add option -entities to command vstate. Within new option command displays information about detection entities.
This commit is contained in:
parent
c19dd45ee0
commit
8e7c8ccf3a
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -57,6 +57,11 @@
|
||||
#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",
|
||||
|
115
tests/bugs/vis/bug25098
Normal file
115
tests/bugs/vis/bug25098
Normal file
@ -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"
|
||||
}
|
@ -26,5 +26,5 @@ vmoveto 100 329
|
||||
vmoveto 0 0
|
||||
vmoveto 200 245
|
||||
vmoveto 0 0
|
||||
vmoveto 300 349
|
||||
vmoveto 300 345
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -28,5 +28,5 @@ vmoveto 100 329
|
||||
vmoveto 0 0
|
||||
vmoveto 200 245
|
||||
vmoveto 0 0
|
||||
vmoveto 300 349
|
||||
vmoveto 300 345
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user