1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0024070: OpenGL capped object-level clipping planes

Graphical clipping:
- Use "Graphic3d_ClipPlane" to defined clipping for PrsMgr_PresentableObject (local clipping), for V3d_View (global clipping).

Get rid of old implementations:
- Remove Visual3d_ClipPlane.
- Port V3d_Plane to Graphic3d_ClipPlane core.

Selection Sensitives:
- Port "Matches" method to add full set of arguments (SelectBasics_PickArgs), including min-max depth coming from selector.
- Get rid of transient data for pair Matches -> ComputeDepth.
- Extend SelectMgr_ViewerSelector::LoadResult to work with local clipping, add virtual callbacks to compute globa/local depth clipping for picking.

Capping rendering algorithm:
- Recursive rendering algorithm for OpenGl_Groups.
- Introduced Rendering filter for groups.

Clipping plane management in TKOpenGl:
- Added OpenGl_ClippingState to OpenGl_Context.

DRAWEXE commands:
- Ported "vclipplane" command for new approach.
- Added "vsettexturemode" command for changing texture details in views (enable / disable textures).

Correct DownCast syntax (compilation error)

Fix new compiler warnings

tests/bugs/vis/bug22906 migrated to the new vclipplane syntax
This commit is contained in:
apl
2013-09-19 16:58:00 +04:00
committed by bugmaster
parent 788cbaf4c4
commit 4269bd1b11
111 changed files with 4168 additions and 2293 deletions

View File

@@ -193,23 +193,6 @@ is
-- 2d point <X,Y>.
is virtual;
DepthMin(me) returns Real from Standard;
---Purpose: Returns the minimum depth value (if clipping plane defined).
--- Should be used when call ::Shoot() to compute eyeline.
---C++: inline
DepthMax(me) returns Real from Standard;
---Purpose: Returns the maximum depth value (if clipping plane defined).
--- Should be used when call ::Shoot() to compute eyeline.
---C++: inline
DepthMinMax(me : mutable;
theDepthMin : in Real from Standard;
theDepthMax : in Real from Standard);
---Purpose: Setup the min/max depth values (doesn't affect
--- projection functionality itself).
--- Should be used when call ::Shoot() to compute eyeline.
Transform(me; P : in out Pnt from gp;
T : GTrsf from gp)
---C++: inline
@@ -230,7 +213,5 @@ fields
myInvTrsf : GTrsf from gp is protected;
myView : View from V3d;
myDepthMin : Real from Standard;
myDepthMax : Real from Standard;
end Projector;

View File

@@ -44,9 +44,7 @@
Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
: myPersp(aViou->Type()==V3d_PERSPECTIVE),
myFocus(aViou->Focale()),
myView(aViou),
myDepthMin(-Precision::Infinite()),
myDepthMax( Precision::Infinite())
myView(aViou)
{
Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ;
//Standard_Boolean Pers=Standard_False;
@@ -72,9 +70,7 @@ Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
Select3D_Projector::Select3D_Projector()
: myPersp(Standard_False),
myFocus(0),
myDepthMin(-Precision::Infinite()),
myDepthMax( Precision::Infinite())
myFocus(0)
{
Scaled();
}
@@ -86,9 +82,7 @@ Select3D_Projector::Select3D_Projector()
Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
: myPersp(Standard_False),
myFocus(0),
myDepthMin(-Precision::Infinite()),
myDepthMax( Precision::Infinite())
myFocus(0)
{
myScaledTrsf.SetTransformation(CS);
myGTrsf.SetTrsf(myScaledTrsf);
@@ -103,9 +97,7 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
const Standard_Real Focus)
: myPersp(Standard_True),
myFocus(Focus),
myDepthMin(-Precision::Infinite()),
myDepthMax( Precision::Infinite())
myFocus(Focus)
{
myScaledTrsf.SetTransformation(CS);
myGTrsf.SetTrsf(myScaledTrsf);
@@ -122,9 +114,7 @@ Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
const Standard_Real Focus)
: myPersp(Persp),
myFocus(Focus),
myScaledTrsf(T),
myDepthMin(-Precision::Infinite()),
myDepthMax( Precision::Infinite())
myScaledTrsf(T)
{
myGTrsf.SetTrsf(myScaledTrsf);
Scaled();
@@ -140,9 +130,7 @@ Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT,
const Standard_Real Focus)
: myPersp(Persp),
myFocus(Focus),
myGTrsf(GT),
myDepthMin(-Precision::Infinite()),
myDepthMax( Precision::Infinite())
myGTrsf(GT)
{
Scaled();
}
@@ -463,10 +451,3 @@ void Select3D_Projector::SetView(const Handle(V3d_View)& aViou)
Scaled();
}
void Select3D_Projector::DepthMinMax (const Standard_Real theDepthMin,
const Standard_Real theDepthMax)
{
myDepthMin = theDepthMin;
myDepthMax = theDepthMax;
}

View File

@@ -126,13 +126,3 @@ inline void Select3D_Projector::Transform (gp_Pnt& Pnt, const gp_GTrsf& T) const
T.Transforms(xyz);
Pnt = gp_Pnt(xyz);
}
inline Standard_Real Select3D_Projector::DepthMin() const
{
return myDepthMin;
}
inline Standard_Real Select3D_Projector::DepthMax() const
{
return myDepthMax;
}

View File

@@ -35,6 +35,7 @@ uses
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Location from TopLoc
@@ -71,17 +72,16 @@ is
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is static;
---Level: Public
---Purpose:
--
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
@@ -97,7 +97,7 @@ is
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
returns Real from Standard;
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;

View File

@@ -65,8 +65,6 @@ Select3D_SensitiveEntity(OwnerId)
void Select3D_SensitiveBox::
Project(const Handle(Select3D_Projector)& aProj)
{
Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
if(HasLocation())
{
Bnd_Box B = mybox3d.Transformed(Location().Transformation());
@@ -103,15 +101,20 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected(const TopLo
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveBox::
Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveBox::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
DMin=0.;
// check that sensitive box passes by depth
Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
if (thePickArgs.IsClipped (aDepth))
{
return Standard_False;
}
theMatchDMin = 0.0;
theMatchDepth = aDepth;
return Standard_True;
}

View File

@@ -34,6 +34,7 @@ uses
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Circle from Geom,
Array1OfPnt from TColgp,
HArray1OfPnt from TColgp,
@@ -95,12 +96,14 @@ is
-- If the length of apolyg3d is more then 1, the first point of apolyg3d
-- must be equal to the last point of apolyg3d.
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is static;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -117,9 +120,16 @@ is
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
ComputeDepth (me;
thePickLine : Lin from gp;
theDetectedIndex : Integer from Standard)
returns Real from Standard;
---Level: Public
---Purpose: Compute depth of sensitive circle for the detected sub-part.
-- @param thePickLine [in] the picking line.
-- @param theDetectedIndex [in] index of the detected sub-part.
-- @return depth on the picking line.
ArrayBounds(me;Low,Up:in out Integer);
GetPoint3d(me;rank:Integer) returns Pnt from gp;
@@ -142,7 +152,6 @@ is
fields
myFillStatus : Boolean;
myDetectedIndex : Integer from Standard; -- used for depth...
myCenter2D : Pnt2d from Select3D; -- used for Matches()
myCenter3D : Pnt from Select3D; -- used for Matches()
myCircle : Circle from Geom;

View File

@@ -72,7 +72,6 @@ Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Integer NbPoints):
Select3D_SensitivePoly(OwnerId, S3D_GetCircleNBPoints(TheCircle,NbPoints)),
myFillStatus(FilledCircle),
myDetectedIndex(-1),
myCircle(TheCircle),
mystart(0),
myend(0)
@@ -129,7 +128,6 @@ Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Integer NbPoints):
Select3D_SensitivePoly(OwnerId, S3D_GetArcNBPoints(TheCircle,NbPoints)),
myFillStatus(FilledCircle),
myDetectedIndex(-1),
myCircle(TheCircle),
mystart(u1),
myend(u2)
@@ -186,7 +184,6 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
const Standard_Boolean FilledCircle):
Select3D_SensitivePoly(OwnerId, Thepolyg3d),
myFillStatus(FilledCircle),
myDetectedIndex(-1),
mystart(0),
myend(0)
{
@@ -206,7 +203,6 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
const Standard_Boolean FilledCircle):
Select3D_SensitivePoly(OwnerId, Thepolyg3d),
myFillStatus(FilledCircle),
myDetectedIndex(-1),
mystart(0),
myend(0)
{
@@ -221,13 +217,13 @@ myend(0)
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveCircle::
Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveCircle::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Standard_Integer aSize = mypolyg.Size();
Standard_Integer aDetectedIndex = -1;
gp_XY aPickXY (thePickArgs.X(), thePickArgs.Y());
if (aSize != 1)
{
Standard_Boolean Found = Standard_False;
@@ -241,15 +237,19 @@ Matches(const Standard_Real X,
Select3D_SensitiveTriangle::Status(mypolyg.Pnt2d(anIndex),
mypolyg.Pnt2d(anIndex+1),
mypolyg.Pnt2d(anIndex+2),
gp_XY(X,Y),aTol,DMin);
aPickXY, thePickArgs.Tolerance(),
theMatchDMin);
Found = (TheStat != 2);
if(Found) myDetectedIndex = anIndex;
if (Found)
{
aDetectedIndex = anIndex;
}
anIndex += 2;
}
}
else
{
myDetectedIndex =-1;
Standard_Real Xmin,Ymin,Xmax,Ymax;
// Get coordinates of the bounding box
@@ -259,32 +259,47 @@ Matches(const Standard_Real X,
// Fill anArrayOf2dPnt with points from mypolig2d
Points2D(anArrayOf2dPnt);
CSLib_Class2d anInOutTool(anArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
CSLib_Class2d anInOutTool (anArrayOf2dPnt,
thePickArgs.Tolerance(),
thePickArgs.Tolerance(),
Xmin, Ymin, Xmax, Ymax);
// Method SiDans returns the status :
// 1 - the point is inside the circle
// 0 - the point is on the circle
// -1 - the point is outside the circle
Standard_Integer aStat = anInOutTool.SiDans(gp_Pnt2d(X,Y));
Standard_Integer aStat = anInOutTool.SiDans (gp_Pnt2d (aPickXY));
if(aStat != -1)
{
// Compute DMin (a distance between the center and the point)
DMin = gp_XY(myCenter2D.x - X, myCenter2D.y - Y).Modulus();
Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
return Standard_True;
theMatchDMin = gp_XY (myCenter2D.x - aPickXY.X(), myCenter2D.y - aPickXY.Y()).Modulus();
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
if(!Found)
myDetectedIndex=-1;
else
Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
return Found;
if (Found)
{
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
// Circle degenerates into point
DMin = gp_Pnt2d(X, Y).Distance(mypolyg.Pnt2d(0));
if (DMin <= aTol*SensitivityFactor())
return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
theMatchDMin = gp_Pnt2d(aPickXY).Distance(mypolyg.Pnt2d(0));
if (theMatchDMin <= thePickArgs.Tolerance() * SensitivityFactor())
{
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
@@ -301,7 +316,6 @@ Matches(const Standard_Real XMin,
const Standard_Real YMax,
const Standard_Real aTol)
{
myDetectedIndex =-1;
Bnd_Box2d abox;
abox.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax));
abox.Enlarge(aTol);
@@ -324,7 +338,6 @@ Matches (const TColgp_Array1OfPnt2d& aPoly,
const Bnd_Box2d& aBox,
const Standard_Real aTol)
{
myDetectedIndex = -1;
Standard_Real Umin,Vmin,Umax,Vmax;
aBox.Get(Umin,Vmin,Umax,Vmax);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
@@ -401,21 +414,23 @@ void Select3D_SensitiveCircle::Dump(Standard_OStream& S,const Standard_Boolean F
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveCircle::ComputeDepth(const gp_Lin& EyeLine) const
Standard_Real Select3D_SensitiveCircle::ComputeDepth (const gp_Lin& thePickLine,
const Standard_Integer theDetectedIndex) const
{
gp_XYZ aCDG;
if(myDetectedIndex==-1)
if (theDetectedIndex == -1)
{
aCDG = myCenter3D;
}
else
{
aCDG += mypolyg.Pnt(myDetectedIndex);
aCDG += mypolyg.Pnt(myDetectedIndex+1);
aCDG += mypolyg.Pnt(myDetectedIndex+2);
aCDG += mypolyg.Pnt (theDetectedIndex);
aCDG += mypolyg.Pnt (theDetectedIndex + 1);
aCDG += mypolyg.Pnt (theDetectedIndex + 2);
aCDG /= 3.;
}
return ElCLib::Parameter(EyeLine,gp_Pnt(aCDG));
return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
}
//=======================================================================

View File

@@ -36,6 +36,7 @@ uses
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Curve from Geom,
Array1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
@@ -72,13 +73,15 @@ is
---Level: Public
---Purpose: Creation of Sensitive Curve from Points.
-- Warning : This Method should disappear in the next version...
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is redefined static;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -95,9 +98,15 @@ is
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
ComputeDepth (me;
thePickLine : Lin from gp;
theDetectedIndex : Integer from Standard)
returns Real from Standard;
---Level: Public
---Purpose: Compute depth of sensitive circle for the detected sub-part.
-- @param thePickLine [in] the picking line.
-- @param theDetectedIndex [in] index of the detected sub-part.
-- @return depth on the picking line.
GetLastDetected(me) returns Integer from Standard;
---Purpose: Gets index of last detected segment

View File

@@ -76,25 +76,27 @@ mylastseg(0)
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveCurve
::Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Standard_Integer Rank;
TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
Points2D(aArrayOf2dPnt);
if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
X, Y,
aTol,
DMin,
thePickArgs.X(), thePickArgs.Y(),
thePickArgs.Tolerance(),
theMatchDMin,
Rank))
{
// remember detected segment (for GetLastDetected)
mylastseg = Rank;
// compute and validate the depth (::Depth()) along the eyeline
return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin);
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank);
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
@@ -189,29 +191,30 @@ void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean Fu
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& EyeLine) const
Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
const Standard_Integer theSegment) const
{
Standard_Real aDepth = Precision::Infinite();
// Not implemented
if(mylastseg==0)
return aDepth;
gp_XYZ aCDG;
// In case if mylastseg and mylastseg+1 are not valid
// the depth will be infinite
if (mylastseg < mypolyg.Size())
if (theSegment == 0)
{
aCDG = mypolyg.Pnt(mylastseg);
if (mylastseg+1 < mypolyg.Size())
{
aCDG += mypolyg.Pnt(mylastseg+1);
aCDG /= 2.;
}
aDepth = ElCLib::Parameter(EyeLine,gp_Pnt(aCDG));
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();
}
gp_XYZ aCDG = mypolyg.Pnt (theSegment);
if (theSegment + 1 < mypolyg.Size())
{
aCDG += mypolyg.Pnt(theSegment + 1);
aCDG /= 2.;
}
return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
}
//=======================================================================

View File

@@ -59,14 +59,12 @@ is
Is3D(me) returns Boolean from Standard is redefined static;
---Purpose: Returns true if this framework provides 3D information.
Project (me:mutable;aProjector : Projector from Select3D) is virtual;
Project (me:mutable;aProjector : Projector from Select3D) is deferred;
---Level: Public
---Purpose:Returns the projector aProjector.
-- In classes inheriting this framework, you must
-- redefine this function in order to get a sensitive 2D
-- rectangle from a 3D entity. This rectangle is the
-- sensitive zone which makes the 3D entity selectable.
---Purpose: In classes inheriting this framework, you must
-- redefine this function in order to get a sensitive 2D
-- rectangle from a 3D entity. This rectangle is the
-- sensitive zone which makes the 3D entity selectable.
MaxBoxes(me) returns Integer is redefined virtual;
---Level: Public
@@ -87,16 +85,6 @@ is
-- sensitive entity which can accept another connected
-- sensitive entity.//can be connected to another sensitive entity.
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean is redefined virtual;
---Purpose: Matches the coordinates X, Y with the entity found at
-- that point within the tolerance aTol and the minimum depth DMin.
-- You must redefine this function for every inheriting entity.
-- You will have to call this framework inside the redefined function.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
@@ -117,23 +105,6 @@ is
returns Boolean from Standard is redefined virtual;
---Purpose: prevents from hiding virtual methods...
GetEyeLine(me; X,Y : Real from Standard) returns Lin from gp;
---Purpose: Returns the eye line for the point defined by the coordinates X,Y.
ComputeDepth(me;EyeLine : Lin from gp) returns Real from Standard
is deferred;
---Purpose: Returns the depth of this object on the line EyeLine.
-- EyeLine goes through the eye towards a point
-- defined by the coordinates X,Y in the function GetEyeLine.
---Purpose: gives an abcissa on <aLin> .
-- <aLin> represents the line going through
-- the eye towards an X,Y point on the screen. This Method
-- must return a mean Depth on this line.
Depth(me) returns Real from Standard is redefined;
---Category: Location of sensitive entities...
-- Default implementations of HasLocation() and Location() rely on
-- location obtained from the entity owner, to minimize memory usage.
@@ -159,15 +130,6 @@ is
UpdateLocation(me:mutable;aLoc:Location from TopLoc);
SetLastPrj(me:mutable;aPrj:Projector from Select3D) is virtual;
SetLastDepth(me:mutable; aDepth: Real from Standard) is protected;
fields
mylastprj : Projector from Select3D is protected;
mylastdepth : ShortReal from Standard;
end SensitiveEntity;

View File

@@ -33,44 +33,9 @@
//=======================================================================
Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId):
SelectBasics_SensitiveEntity(OwnerId),
mylastprj(),
mylastdepth(ShortRealLast())
SelectBasics_SensitiveEntity(OwnerId)
{}
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::Project(const Handle(Select3D_Projector)& aPrj)
{
mylastprj = aPrj;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveEntity::Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real /*aTol*/,
Standard_Real& /*DMin*/)
{
if (!mylastprj.IsNull())
{
gp_Lin L = mylastprj->Shoot (X, Y);
SetLastDepth (ComputeDepth (L));
return (mylastdepth > mylastprj->DepthMin()) && (mylastdepth < mylastprj->DepthMax());
}
else
{
SetLastDepth (ComputeDepth (gp_Lin())); // how we determine depth without eyeline here?
return (mylastdepth > ShortRealFirst()) && (mylastdepth < ShortRealLast());
}
}
//=======================================================================
//function : Matches
//purpose :
@@ -189,30 +154,6 @@ Standard_Boolean Select3D_SensitiveEntity::HasLocation() const
Standard_Boolean Select3D_SensitiveEntity::Is3D() const
{return Standard_True;}
//=======================================================================
//function : Depth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveEntity::Depth() const
{return mylastdepth;}
//=======================================================================
//function : GetEyeLine
//purpose :
//=======================================================================
gp_Lin Select3D_SensitiveEntity::GetEyeLine(const Standard_Real X,
const Standard_Real Y) const
{
gp_Lin L;
if (!mylastprj.IsNull())
{
L = mylastprj->Shoot (X, Y);
}
return L;
}
//=======================================================================
//function : MaxBoxes
//purpose :
@@ -221,15 +162,6 @@ gp_Lin Select3D_SensitiveEntity::GetEyeLine(const Standard_Real X,
Standard_Integer Select3D_SensitiveEntity::MaxBoxes() const
{return 1;}
//=======================================================================
//function : SetLastPrj
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::SetLastPrj(const Handle(Select3D_Projector)& aprj)
{ mylastprj = aprj; }
//=======================================================================
//function : GetConnected
//purpose :
@@ -240,12 +172,3 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected(const To
Handle(Select3D_SensitiveEntity) NiouEnt;
return NiouEnt;
}
//=======================================================================
//function : SetLastDepth
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::SetLastDepth(const Standard_Real aDepth)
{
mylastdepth = DToF(aDepth);
}

View File

@@ -32,6 +32,7 @@ uses
Projector from Select3D,
Lin from gp,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt from TColgp,
HArray1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
@@ -66,12 +67,14 @@ is
-- the sensitivity type Sensitivity.
-- The array of points is the outer polygon of the geometric face.
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is redefined virtual;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined virtual;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -89,14 +92,22 @@ is
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined virtual;
ComputeDepth (me;
thePickLine : Lin from gp;
theDepthMin, theDepthMax : Real from Standard)
returns Real from Standard
is virtual;
---Level: Public
---Purpose: Computes the depth values for all 3D points defining this face and returns
-- the minimal value among them.
-- the minimal value among them.
-- If the "minimal depth" approach is not suitable and gives wrong detection results
-- in some particular case, a custom sensitive face class can be implemented at application level
-- that overrides default ComputeDepth() behavior.
-- in some particular case, a custom sensitive face class can redefine this method.
ComputeDepth(me;EyeLine: Lin from gp)
is private;
---Level: Public
---Purpose: Warning: Obsolete.
-- Use newer version of the method with min, max limits passed as arguments.
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
@@ -110,6 +121,4 @@ is
fields
mytype : TypeOfSensitivity;
myautointer : Boolean;
end SensitiveFace;

View File

@@ -32,18 +32,6 @@
#include <CSLib_Class2d.hxx>
#define AutoInterMask 0x01
#define AutoComputeMask 0x02
// Standard_True if the flag is one
#define AutoInterFlag(aflag) ( aflag & AutoInterMask )
#define AutoComputeFlag(aflag) ( aflag & AutoComputeMask )
// set the flag to one
#define SetAutoInterFlag(aflag) ( aflag = aflag & AutoInterMask)
#define SetAutoComputeFlag(aflag) ( aflag = aflag & AutoComputeMask)
// Initialize flags
#define AutoInitFlags(aflag) (aflag = 0)
//==================================================
// Function: Hide this constructor to the next version...
// Purpose : simply avoid interfering with the version update
@@ -56,7 +44,6 @@ Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
Select3D_SensitivePoly(OwnerId, ThePoints),
mytype (aType)
{
AutoInitFlags(myautointer);
}
//==================================================
@@ -71,7 +58,6 @@ Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
Select3D_SensitivePoly(OwnerId, ThePoints),
mytype (aType)
{
AutoInitFlags(myautointer);
}
//==================================================
@@ -79,11 +65,9 @@ mytype (aType)
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveFace::
Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Standard_Real DMin2 = 0.;
Standard_Real Xmin = 0.,Ymin = 0.,Xmax = 0.,Ymax = 0.;
@@ -96,7 +80,7 @@ Matches(const Standard_Real X,
// from start Dmin = size of the bounding box 2D,
// then min. distance of the polyhedron or cdg...
Standard_Real aTol2 = aTol*aTol;
Standard_Real aTol2 = thePickArgs.Tolerance() * thePickArgs.Tolerance();
Standard_Integer aSize = mypolyg.Size(), anIndex;
gp_XY CDG;
for(anIndex=0;anIndex<aSize;++anIndex)
@@ -108,14 +92,14 @@ Matches(const Standard_Real X,
{
CDG/=(aSize-1);
}
DMin2=Min(DMin2,gp_XY(CDG.X()-X,CDG.Y()-Y).SquareModulus());
DMin = Sqrt(DMin2);
DMin2 = Min (DMin2, gp_XY (CDG.X() - thePickArgs.X(), CDG.Y() - thePickArgs.Y()).SquareModulus());
theMatchDMin = Sqrt(DMin2);
Standard_Boolean isplane2d(Standard_True);
for(anIndex=1;anIndex<aSize;++anIndex)
{
gp_XY V1(mypolyg.Pnt2d(anIndex)),V(X,Y);
gp_XY V1(mypolyg.Pnt2d(anIndex)),V(thePickArgs.X(), thePickArgs.Y());
V1-=mypolyg.Pnt2d(anIndex-1);
V-=mypolyg.Pnt2d(anIndex-1);
Standard_Real Vector = V1^V;
@@ -128,18 +112,25 @@ Matches(const Standard_Real X,
gp_XY PlaneTest(CDG);
PlaneTest-=mypolyg.Pnt2d(anIndex-1);
Standard_Real valtst = PlaneTest^V1;
if(isplane2d && Abs(valtst)>aTol) isplane2d=Standard_False;
if(isplane2d && Abs(valtst) > thePickArgs.Tolerance()) isplane2d=Standard_False;
}
if (isplane2d)
{
return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
thePickArgs.DepthMin(),
thePickArgs.DepthMax());
return !thePickArgs.IsClipped (theMatchDepth);
}
//otherwise it is checked if the point is in the face...
TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize);
Points2D(aArrayOf2dPnt);
CSLib_Class2d TheInOutTool(aArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
Standard_Integer TheStat = TheInOutTool.SiDans(gp_Pnt2d(X,Y));
CSLib_Class2d TheInOutTool (aArrayOf2dPnt,
thePickArgs.Tolerance(),
thePickArgs.Tolerance(),
Xmin, Ymin, Xmax, Ymax);
Standard_Integer TheStat = TheInOutTool.SiDans (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()));
Standard_Boolean res(Standard_False);
switch(TheStat)
@@ -154,7 +145,11 @@ Matches(const Standard_Real X,
}
if (res)
{
return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
thePickArgs.DepthMin(),
thePickArgs.DepthMax());
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
@@ -232,25 +227,34 @@ void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean Ful
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveFace::ComputeDepth(const gp_Lin& EyeLine) const
Standard_Real Select3D_SensitiveFace::ComputeDepth (const gp_Lin& thePickLine,
const Standard_Real theDepthMin,
const Standard_Real theDepthMax) const
{
Standard_Real aDepth = Precision::Infinite();
Standard_Real aDepthMin = !mylastprj.IsNull() ? mylastprj->DepthMin() : -Precision::Infinite();
Standard_Real aDepthMax = !mylastprj.IsNull() ? mylastprj->DepthMax() : Precision::Infinite();
Standard_Real aDepthTest;
Standard_Real aPointDepth;
for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex)
{
aDepthTest = ElCLib::Parameter (EyeLine, mypolyg.Pnt(anIndex));
if (aDepthTest < aDepth && (aDepthTest > aDepthMin) && (aDepthTest < aDepthMax))
aPointDepth = ElCLib::Parameter (thePickLine, mypolyg.Pnt(anIndex));
if (aPointDepth < aDepth && (aPointDepth > theDepthMin) && (aPointDepth < theDepthMax))
{
aDepth = aDepthTest;
aDepth = aPointDepth;
}
}
return aDepth;
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const
{
// this method is obsolete.
}
//=======================================================================
//function : GetConnected
//purpose :

View File

@@ -38,6 +38,7 @@ uses
SensitiveEntity from Select3D,
ListOfSensitive from Select3D,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc
@@ -115,15 +116,14 @@ is
ResetLocation(me:mutable) is redefined static;
---Purpose: propagation of location on all the sensitive inside...
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -138,14 +138,6 @@ is
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
---Purpose: returns the depth of the touched entity
SetLastPrj(me:mutable;aPrj:Projector from Select3D) is redefined virtual;
Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static;
---Purpose: Sets the owner for all entities in group
@@ -160,8 +152,5 @@ is
fields
myList : ListOfSensitive from Select3D;
myMustMatchAll : Boolean from Standard;
myLastRank : Integer from Standard;
myLastTol : ShortReal from Standard;
myX,myY : ShortReal from Standard;
end SensitiveGroup;

View File

@@ -31,10 +31,7 @@
Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Boolean MatchAll):
Select3D_SensitiveEntity(OwnerId),
myMustMatchAll(MatchAll),
myLastRank(0),
myX(0.),
myY(0.)
myMustMatchAll(MatchAll)
{
}
@@ -47,10 +44,7 @@ Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_Entit
Select3D_ListOfSensitive& TheList,
const Standard_Boolean MatchAll):
Select3D_SensitiveEntity(OwnerId),
myMustMatchAll(MatchAll),
myLastRank(0),
myX(0.),
myY(0.)
myMustMatchAll(MatchAll)
{
myList.Append(TheList);
}
@@ -124,8 +118,6 @@ void Select3D_SensitiveGroup::Clear()
void Select3D_SensitiveGroup::Project(const Handle(Select3D_Projector)& aProjector)
{
Select3D_SensitiveEntity::Project(aProjector); // to set the field last proj...
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
It.Value()->Project(aProjector);
@@ -215,28 +207,34 @@ void Select3D_SensitiveGroup::ResetLocation()
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveGroup::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
myLastRank = 0;
myLastTol = (Standard_ShortReal)aTol;
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
myLastRank++;
if (It.Value()->Matches (X, Y, aTol, DMin))
theMatchDMin = RealLast();
theMatchDepth = RealLast();
Standard_Real aChildDMin, aChildDepth;
Standard_Boolean isMatched = Standard_False;
Select3D_ListIteratorOfListOfSensitive anIt (myList);
for (; anIt.More(); anIt.Next())
{
Handle(SelectBasics_SensitiveEntity)& aChild = anIt.Value();
if (!aChild->Matches (thePickArgs, aChildDMin, aChildDepth))
{
myX = (Standard_ShortReal)X;
myY = (Standard_ShortReal)Y;
myLastTol = (Standard_ShortReal)aTol;
// compute and validate the depth (will call ::ComputeDepth())
return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin);
continue;
}
if (!isMatched)
{
theMatchDMin = aChildDMin;
isMatched = Standard_True;
}
theMatchDepth = Min (aChildDepth, theMatchDepth);
}
// no match
myLastRank = 0;
SetLastDepth (ShortRealLast());
return Standard_False;
return isMatched;
}
//=======================================================================
@@ -301,37 +299,6 @@ Matches (const TColgp_Array1OfPnt2d& aPoly,
return result;
}
//=======================================================================
//function : ComputeDepth
//purpose : to optimise, the minimum depth for
// entities that answer YES to Matches(X,Y,...) is taken
// the test is started from mylastRank...
//=======================================================================
Standard_Real Select3D_SensitiveGroup::ComputeDepth(const gp_Lin& EyeLine) const
{
Standard_Integer currank = 0;
Standard_Real DMin, thedepth (Precision::Infinite());
for (Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
currank++;
if (currank >= myLastRank)
{
// this recomputes and validates the depth for the entity
if (It.Value()->Matches (myX, myY, myLastTol, DMin))
{
It.Value()->ComputeDepth (EyeLine);
if (It.Value()->Depth() < thedepth)
{
// search for topmost entity
thedepth = It.Value()->Depth();
//myLastRank = currank; // can not do this here...
}
}
}
}
return thedepth;
}
//=======================================================================
//function : MaxBoxes
//purpose :
@@ -346,18 +313,6 @@ Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const
return nbboxes;
}
//=======================================================================
//function : SetLastPrj
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::SetLastPrj(const Handle(Select3D_Projector)& Prj)
{
Select3D_SensitiveEntity::SetLastPrj(Prj);
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
It.Value()->SetLastPrj(Prj);
}
//=======================================================================
//function : Set
//purpose :

View File

@@ -32,6 +32,7 @@ uses
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Location from TopLoc,
Box2d from Bnd,
Array1OfPnt2d from TColgp,
@@ -62,16 +63,15 @@ is
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is redefined static;
---Level: Public
---Purpose: returns true if the X,Y position matches the point
-- else gives the distance between them.
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -90,7 +90,7 @@ is
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
returns Real from Standard;
Point(me) returns Pnt from gp;

View File

@@ -50,7 +50,6 @@ Select3D_SensitiveEntity(anOwner)
void Select3D_SensitivePoint
::Project (const Handle(Select3D_Projector)& aProj)
{
Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
gp_Pnt2d aPoint2d;
if(!HasLocation())
aProj->Project(mypoint, aPoint2d);
@@ -80,19 +79,26 @@ void Select3D_SensitivePoint
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitivePoint
::Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitivePoint::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
DMin = gp_Pnt2d(X,Y).Distance(myprojpt);
if(DMin<=aTol*SensitivityFactor())
// check coordinate matching
Standard_Real aDist = gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()).Distance (myprojpt);
if (aDist > thePickArgs.Tolerance() * SensitivityFactor())
{
// compute and validate the depth (::Depth()) along the eyeline
return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
return Standard_False;
}
return Standard_False;
Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
if (thePickArgs.IsClipped (aDepth))
{
return Standard_False;
}
theMatchDMin = aDist;
theMatchDepth = aDepth;
return Standard_True;
}
//==================================================

View File

@@ -74,7 +74,6 @@ mypolyg(NbPoints)
void Select3D_SensitivePoly::Project(const Handle(Select3D_Projector)& aProj)
{
Select3D_SensitiveEntity:: Project (aProj); // to set the field last proj...
mybox2d.SetVoid();
Standard_Boolean hasloc = HasLocation();

View File

@@ -38,6 +38,7 @@ uses
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc,
@@ -112,16 +113,15 @@ is
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -139,7 +139,7 @@ is
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
returns Real from Standard;
MaxBoxes(me) returns Integer is redefined static;
---Level: Public

View File

@@ -62,7 +62,6 @@ mymaxrect(MaxRect)
void Select3D_SensitiveSegment
::Project(const Handle(Select3D_Projector)& aProj)
{
Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
gp_Pnt2d aPoint2dStart;
gp_Pnt2d aPoint2dEnd;
@@ -137,17 +136,24 @@ void Select3D_SensitiveSegment
// Purpose :
//=====================================================
Standard_Boolean Select3D_SensitiveSegment
::Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveSegment::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
gp_Pnt2d aPStart(myprojstart.x,myprojstart.y);
gp_Pnt2d aPEnd(myprojend.x,myprojend.y);
if ( ! SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd, X, Y, aTol, DMin) )
gp_Pnt2d aPStart (myprojstart.x,myprojstart.y);
gp_Pnt2d aPEnd (myprojend.x,myprojend.y);
if (!SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd,
thePickArgs.X(),
thePickArgs.Y(),
thePickArgs.Tolerance(),
theMatchDMin))
{
return Standard_False;
return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin); // compute and validate depth
}
theMatchDepth = ComputeDepth (thePickArgs.PickLine());
return !thePickArgs.IsClipped (theMatchDepth);
}
//=====================================================

View File

@@ -33,6 +33,7 @@ uses
Projector from Select3D,
Lin from gp,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
XY from gp,
@@ -54,12 +55,14 @@ is
---Purpose: Constructs a sensitive triangle object defined by the
-- owner OwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity.
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
returns Boolean
is redefined virtual;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -78,7 +81,7 @@ is
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
returns Real from Standard;
Points3D(me; P1,P2,P3 : out Pnt from gp) ;

View File

@@ -79,28 +79,37 @@ mytype (aType)
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveTriangle::
Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
Standard_Boolean Select3D_SensitiveTriangle::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
if(Bnd_Box2d(mybox2d).IsOut(gp_Pnt2d(X,Y))) return Standard_False;
Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
if (thePickArgs.IsClipped (aDepth))
{
return Standard_False;
}
theMatchDepth = aDepth;
if (Bnd_Box2d (mybox2d).IsOut (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y())))
{
return Standard_False;
}
Standard_Integer Res;
switch (mytype)
{
case Select3D_TOS_BOUNDARY:
Res = Status(X,Y,aTol,DMin);
Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
return Res== 1;
break;
case Select3D_TOS_INTERIOR:
Res = Status(X,Y,aTol,DMin);
Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
return (Res==0 || Res == 1);
default:
break;
}
return Standard_True;
}

View File

@@ -31,6 +31,7 @@ uses
Lin from gp,
Trsf from gp,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
HArray1OfInteger from TColStd,
@@ -83,12 +84,15 @@ is
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -104,12 +108,16 @@ is
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
---Purpose: give the depht of the last detected triangle
-- (center of gravity)
ComputeDepth (me;
thePickLine : Lin from gp;
theTriangle : Integer from Standard)
returns Real from Standard;
---Level: Public
---Purpose: Compute precise depth of detected triangle.
-- @param thePickLine [in] the picking line.
-- @param theTriangle [in] the index of detected triangle.
-- @return depth on the picking line.
DetectedTriangle(me) returns Integer from Standard;
---Purpose: Returns the detected three nodes P1, P2, P3 constituting a triangle.

View File

@@ -207,8 +207,6 @@ myDetectedTr(-1)
void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj)
{
Select3D_SensitiveEntity::Project(aPrj); // to set the field last proj...
mybox2d.SetVoid();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
@@ -241,27 +239,25 @@ void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes)
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::
Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
{
// get view direction (necessary for calculation of depth) from field mylastprj of the base class
if (mylastprj.IsNull())
return Standard_False;
DMin = Precision::Infinite();
gp_XY BidPoint(X,Y);
Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
theMatchDMin = Precision::Infinite();
gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y());
myDetectedTr = -1;
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
// it is checked if we are inside the triangle 2d.
if(myIntFlag)
{
gp_Lin EyeLine = mylastprj->Shoot(X,Y);
if ( myTrsf.Form()!=gp_Identity )
EyeLine.Transform (myTrsf.Inverted());
gp_Lin aPickingLine = thePickArgs.PickLine();
if (myTrsf.Form() != gp_Identity)
{
aPickingLine.Transform (myTrsf.Inverted());
}
Standard_Real aMinDepth = Precision::Infinite();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
@@ -274,24 +270,22 @@ Matches(const Standard_Real X,
const gp_XY& aPnt2d3 = myNodes2d(n3).XY();
gp_XY aUV;
Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV);
if ( aDistSquare > aTol * aTol )
if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance())
continue;
// compute depth on this triangle
Standard_Real aDepth1 = ElCLib::Parameter (EyeLine, Nodes(n1));
Standard_Real aDepth2 = ElCLib::Parameter (EyeLine, Nodes(n2));
Standard_Real aDepth3 = ElCLib::Parameter (EyeLine, Nodes(n3));
// get interpolated depth of the triangle nodes
Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1));
Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2));
Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3));
Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) +
aUV.Y() * (aDepth3 - aDepth1);
// take triangle with lowest depth and within defined depth interval
if (aDepth < aMinDepth &&
aDepth > mylastprj->DepthMin() &&
aDepth < mylastprj->DepthMax())
// accept triangle with lowest depth and within defined depth interval
if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth))
{
aMinDepth = aDepth;
myDetectedTr = itr;
DMin = Sqrt (aDistSquare);
theMatchDMin = Sqrt (aDistSquare);
}
}
}
@@ -312,7 +306,7 @@ Matches(const Standard_Real X,
Node2 = FreeE(ifri+1);
if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(),
myNodes2d(Node2).XY(),
BidPoint, aTol, DMin) )
BidPoint, thePickArgs.Tolerance(), theMatchDMin))
{
for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++)
{
@@ -330,10 +324,13 @@ Matches(const Standard_Real X,
if ( myDetectedTr <= 0 )
return Standard_False;
// compute and validate the depth (::Depth()) along the eyeline
return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
}
// get precise depth for the detected triangle
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr);
// this test should not fail if the topmost triangle is taken from the
// first if-case block (for other cases this test make sense?)
return !thePickArgs.IsClipped (theMatchDepth);
}
//=======================================================================
//function : Matches
@@ -509,86 +506,117 @@ void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Bo
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& EyeLine) const
Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine,
const Standard_Integer theTriangle) const
{
if(myDetectedTr==-1) return Precision::Infinite(); // currently not implemented...
if (theTriangle == -1)
{
return Precision::Infinite(); // currently not implemented...
}
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
Standard_Integer n1,n2,n3;
triangles(myDetectedTr).Get(n1,n2,n3);
triangles (theTriangle).Get (n1,n2,n3);
gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)};
if(myTrsf.Form()!=gp_Identity)
if (myTrsf.Form() != gp_Identity)
{
for(Standard_Integer i =0;i<=2;i++)
for (Standard_Integer i =0; i<=2; i++)
{
P[i].Transform(myTrsf);
P[i].Transform (myTrsf);
}
}
// formula calculate the parameter of the point on the intersection
// t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir)
Standard_Real prof(Precision::Infinite());
gp_Pnt Oye = EyeLine.Location(); // origin of the target line eye/point...
gp_Dir Dir = EyeLine.Direction();
Standard_Real prof (Precision::Infinite());
gp_Pnt Oye = thePickLine.Location(); // origin of the target line eye/point...
gp_Dir Dir = thePickLine.Direction();
gp_Vec Vtr[3];
for(Standard_Integer i=0;i<=2;i++)
Vtr[i] = gp_Vec(P[i%3],P[(i+1)%3]);
for (Standard_Integer i=0; i<=2; i++)
{
Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]);
}
Vtr[2] = -Vtr[2];
// remove singular cases immediately...
Standard_Integer SingularCase(-1);
if(Vtr[0].SquareMagnitude()<= Precision::Confusion())
Standard_Integer SingularCase (-1);
if (Vtr[0].SquareMagnitude() <= Precision::Confusion())
{
SingularCase = 0;
if(Vtr[1].SquareMagnitude()<= Precision::Confusion())
}
if (Vtr[1].SquareMagnitude() <= Precision::Confusion())
{
SingularCase = (SingularCase == -1) ? 1 : 2;
}
#ifdef BUC60858
if(Vtr[2].SquareMagnitude()<= Precision::Confusion())
if (Vtr[2].SquareMagnitude() <= Precision::Confusion())
{
if( SingularCase < 0 ) SingularCase = 1;
}
#endif
// 3 pts mixed...
if(SingularCase ==2)
if (SingularCase ==2)
{
prof= ElCLib::Parameter(EyeLine,P[0]);
prof = ElCLib::Parameter (thePickLine, P[0]);
return prof;
}
if(SingularCase!=0)
if (SingularCase!=0)
{
Vtr[0].Normalize();
if(SingularCase!=1 &&
SingularCase!=2)
}
if (SingularCase!=1 && SingularCase!=2)
{
Vtr[2].Normalize();
gp_Vec OPo(Oye,P[0]);
}
gp_Vec OPo (Oye, P[0]);
// 2 points mixed... the intersection between the segment and the target line eye/point.
//
if(SingularCase!=-1)
if (SingularCase!=-1)
{
gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0];
gp_Vec Det = Dir^V;
gp_Vec VSM = OPo^V;
if(Det.X()> Precision::Confusion())
prof = VSM.X()/Det.X();
else if (Det.Y()> Precision::Confusion())
prof = VSM.Y()/Det.Y();
else if(Det.Z()> Precision::Confusion())
prof = VSM.Z()/Det.Z();
if (Det.X() > Precision::Confusion())
{
prof = VSM.X() / Det.X();
}
else if (Det.Y() > Precision::Confusion())
{
prof = VSM.Y() / Det.Y();
}
else if (Det.Z() > Precision::Confusion())
{
prof = VSM.Z() / Det.Z();
}
}
else
{
Standard_Real val1 = OPo.DotCross(Vtr[0],Vtr[2]);
Standard_Real val2 = Dir.DotCross(Vtr[0],Vtr[2]);
Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]);
Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]);
if(Abs(val2)>Precision::Confusion())
prof =val1/val2;
if (Abs (val2) > Precision::Confusion())
{
prof = val1 / val2;
}
}
if (prof==Precision::Infinite())
if (prof == Precision::Infinite())
{
prof= ElCLib::Parameter(EyeLine,P[0]);
prof = Min (prof, ElCLib::Parameter(EyeLine,P[1]));
prof = Min (prof, ElCLib::Parameter(EyeLine,P[2]));
prof= ElCLib::Parameter (thePickLine, P[0]);
prof = Min (prof, ElCLib::Parameter (thePickLine, P[1]));
prof = Min (prof, ElCLib::Parameter (thePickLine, P[2]));
}
return prof;

View File

@@ -34,6 +34,7 @@ uses
SensitiveEntity from Select3D,
SensitiveEntitySequence from Select3D,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc
@@ -76,15 +77,15 @@ is
ResetLocation(me:mutable) is redefined static;
---Purpose: propagation of location on all the sensitive inside...
Matches(me :mutable;
X,Y : Real from Standard;
aTol: Real from Standard;
DMin: out Real from Standard)
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean
is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
@@ -101,10 +102,6 @@ is
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard is redefined static;
---Purpose: returns the depth of the touched entity
MaxBoxes(me) returns Integer is redefined static;
---Level: Public
---Purpose:returns <mymaxrect>
@@ -114,9 +111,7 @@ is
Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static;
---Purpose: Sets the owner for all entities in wire
SetLastPrj(me:mutable;aPrj: Projector from Select3D) is redefined virtual;
GetLastDetected(me)
returns SensitiveEntity from Select3D is static;
---Purpose:returns <mymaxrect>

View File

@@ -104,12 +104,12 @@ void Select3D_SensitiveWire::ResetLocation()
// Function : Project
// Purpose :
//=====================================================
void Select3D_SensitiveWire
::Project(const Handle(Select3D_Projector)& aProj)
void Select3D_SensitiveWire::Project(const Handle(Select3D_Projector)& aProj)
{
for(Standard_Integer i=1; i<=mysensitive.Length(); i++)
mysensitive(i)->Project(aProj);
Select3D_SensitiveEntity::Project(aProj);
for (Standard_Integer aSensIt = 1; aSensIt <= mysensitive.Length(); aSensIt++)
{
mysensitive (aSensIt)->Project (aProj);
}
}
//=====================================================
@@ -136,33 +136,37 @@ void Select3D_SensitiveWire
// Function : Matches
// Purpose :
//=====================================================
Standard_Boolean Select3D_SensitiveWire
::Matches(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin)
{
Standard_Integer i;
Standard_Real Dcur;
DMin = Precision::Infinite();
Standard_Boolean IsTouched = Standard_False;
for (i=1; i<=mysensitive.Length(); i++)
{
if (mysensitive.Value(i)->Matches(X,Y,aTol,Dcur))
{
IsTouched = Standard_True;
if(Dcur<=DMin)
{
myDetectedIndex = i;
DMin = Dcur;
}
}
}
if ( ! IsTouched )
return Standard_False;
// compute and validate the depth (::Depth()) along the eyeline
return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
Standard_Boolean Select3D_SensitiveWire::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
theMatchDMin = RealLast();
theMatchDepth = RealLast();
Standard_Real aSegDMin, aSegDepth;
Standard_Boolean isMatched = Standard_False;
myDetectedIndex = -1;
for (Standard_Integer aSegIt = 1; aSegIt <= mysensitive.Length(); aSegIt++)
{
const Handle(SelectBasics_SensitiveEntity)& aSeg = mysensitive.Value (aSegIt);
if (!aSeg->Matches (thePickArgs, aSegDMin, aSegDepth))
{
continue;
}
isMatched = Standard_True;
if (aSegDMin > theMatchDMin)
{
continue;
}
myDetectedIndex = aSegIt;
theMatchDMin = aSegDMin;
theMatchDepth = aSegDepth;
}
return isMatched;
}
//=====================================================
@@ -256,34 +260,6 @@ void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean Ful
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveWire::ComputeDepth(const gp_Lin& EyeLine) const
{
if(myDetectedIndex==-1)
// should be never called...
return Precision::Infinite();
return mysensitive(myDetectedIndex)->ComputeDepth(EyeLine);
}
//=======================================================================
//function : SetLastPrj
//purpose :
//=======================================================================
void Select3D_SensitiveWire::SetLastPrj(const Handle(Select3D_Projector)& Prj)
{
Select3D_SensitiveEntity::SetLastPrj(Prj);
for(Standard_Integer i=1;i<=mysensitive.Length();i++)
mysensitive(i)->SetLastPrj(Prj);
}
//=======================================================================
//function : GetEdges
//purpose : returns the sensitive edges stored in this wire