1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0026195: Visualization - optimize selection algorithms

- initial transformation of triangulation is now applied to selecting frustum;
- switched from NCollection_Vec3 to gp collections to avoid conversions and usage of macros;
- calculation of frustum was refactored to reduce its build time;
- double pixel tolerances for selection were replaced by integer ones;
- switched to splitting along the main axis only in SelectMgr BVH selection primitive sets.
This commit is contained in:
vpa
2015-08-31 10:29:53 +03:00
committed by bugmaster
parent 646529083a
commit 3bf9a45f7a
50 changed files with 1057 additions and 978 deletions

View File

@@ -98,7 +98,7 @@ Standard_Boolean Select3D_SensitiveBox::Matches (SelectBasics_SelectingVolumeMan
}
Standard_Real aDepth;
if (!theMgr.Overlaps (myBox, aDepth)) // check for overlap
if (!theMgr.Overlaps (myBox.CornerMin(), myBox.CornerMax(), aDepth)) // check for overlap
{
return Standard_False;
}

View File

@@ -106,7 +106,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
SetSensitivityFactor (6);
}
}
@@ -164,7 +164,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_En
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
SetSensitivityFactor (6);
}
}
@@ -175,7 +175,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_En
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled)
: Select3D_SensitivePoly (theOwnerId, thePnts3d, (Standard_Boolean )!theIsFilled),
: Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)),
myStart (0),
myEnd (0)
{
@@ -188,7 +188,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
SetSensitivityFactor (6);
}
}
@@ -213,7 +213,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
SetSensitivityFactor (6);
}
}
@@ -256,8 +256,7 @@ Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolume
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
{
Standard_Real aDummy;
if (!theMgr.Overlaps (anArrayOfPnt->Value (aPntIdx), aDummy))
if (!theMgr.Overlaps (anArrayOfPnt->Value (aPntIdx)))
return Standard_False;
}
return Standard_True;

View File

@@ -30,7 +30,7 @@ Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_Enti
myCurve (theCurve)
{
loadPoints (theCurve, theNbPnts);
SetSensitivityFactor (3.0);
SetSensitivityFactor (3);
}
//==================================================
@@ -42,7 +42,7 @@ Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_Enti
: Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True)
{
SetSensitivityFactor (3.0);
SetSensitivityFactor (3);
}
//==================================================
@@ -53,7 +53,7 @@ Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_Enti
const TColgp_Array1OfPnt& thePoints)
: Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True)
{
SetSensitivityFactor (3.0);
SetSensitivityFactor (3);
}
//==================================================

View File

@@ -23,10 +23,9 @@
//=======================================================================
//function : Select3D_SensitiveEntity
//purpose :
//purpose :
//=======================================================================
Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& theOwnerId)
Select3D_SensitiveEntity::Select3D_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId)
: SelectBasics_SensitiveEntity (theOwnerId) {}
//=======================================================================
@@ -69,3 +68,22 @@ void Select3D_SensitiveEntity::Clear()
{
Set (NULL);
}
//=======================================================================
// function : HasInitLocation
// purpose : Returns true if the shape corresponding to the entity has init location
//=======================================================================
Standard_Boolean Select3D_SensitiveEntity::HasInitLocation() const
{
return Standard_False;
}
//=======================================================================
// function : InvInitLocation
// purpose : Returns inversed location transformation matrix if the shape corresponding
// to this entity has init location set. Otherwise, returns identity matrix.
//=======================================================================
gp_Trsf Select3D_SensitiveEntity::InvInitLocation() const
{
return gp_Trsf();
}

View File

@@ -78,6 +78,13 @@ public:
//! Clears up all resources and memory
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
//! Returns true if the shape corresponding to the entity has init location
Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
//! Returns inversed location transformation matrix if the shape corresponding
//! to this entity has init location set. Otherwise, returns identity matrix.
Standard_EXPORT virtual gp_Trsf InvInitLocation() const;
DEFINE_STANDARD_RTTI(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
protected:

View File

@@ -27,7 +27,7 @@ Select3D_SensitivePoint::Select3D_SensitivePoint (const Handle(SelectBasics_Enti
const gp_Pnt& thePoint)
: Select3D_SensitiveEntity (theOwner)
{
SetSensitivityFactor (12.0);
SetSensitivityFactor (12);
myPoint = thePoint;
}

View File

@@ -248,9 +248,8 @@ Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_Selecting
{
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
Standard_Real aDummy;
return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0), aDummy)
&& theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1), aDummy);
return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
&& theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
}
//==================================================

View File

@@ -52,10 +52,9 @@ Standard_Boolean Select3D_SensitiveTriangle::Matches (SelectBasics_SelectingVolu
Standard_Real aDistToCOG = RealLast();
if (!theMgr.IsOverlapAllowed())
{
Standard_Real aDummy;
return theMgr.Overlaps (myPoints[0], aDummy)
&& theMgr.Overlaps (myPoints[1], aDummy)
&& theMgr.Overlaps (myPoints[2], aDummy);
return theMgr.Overlaps (myPoints[0])
&& theMgr.Overlaps (myPoints[1])
&& theMgr.Overlaps (myPoints[2]);
}
if (!theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], mySensType, aDepth))

View File

@@ -54,6 +54,7 @@ Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(S
myInitLocation (theInitLoc),
myDetectedTr (-1)
{
myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& aNodes = myTriangul->Nodes();
@@ -146,6 +147,7 @@ Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(S
myFreeEdges (theFreeEdges),
myDetectedTr (-1)
{
myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myPrimitivesNb = theIsInterior ? theTrg->Triangles().Length() : theFreeEdges->Length() / 2;
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
@@ -185,19 +187,15 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer t
Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx);
SelectMgr_Vec3 aMinPnt (RealLast());
SelectMgr_Vec3 aMaxPnt (RealFirst());
Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_INTERIOR)
{
Standard_Integer aNode1, aNode2, aNode3;
myTriangul->Triangles() (aPrimIdx + 1).Get (aNode1, aNode2, aNode3);
gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode1);
gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode3);
gp_Pnt aPnt1 = myTriangul->Nodes().Value (aNode1);
gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())),
Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())),
@@ -210,10 +208,8 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer t
{
Standard_Integer aNodeIdx1 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx);
Standard_Integer aNodeIdx2 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx + 1);
gp_Pnt aNode1 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx1).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNodeIdx1);
gp_Pnt aNode2 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNodeIdx2);
gp_Pnt aNode1 = myTriangul->Nodes().Value (aNodeIdx1);
gp_Pnt aNode2 = myTriangul->Nodes().Value (aNodeIdx2);
aMinPnt = SelectMgr_Vec3 (Min (aNode1.X(), aNode2.X()),
Min (aNode1.Y(), aNode2.Y()),
@@ -264,17 +260,14 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
Standard_Real& theMatchDepth)
{
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_BOUNDARY)
{
Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1);
Standard_Integer aSegmEndIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 2);
Handle(TColgp_HArray1OfPnt) anEdgePnts = new TColgp_HArray1OfPnt (1, 2);
gp_Pnt aSegmStart = hasInitLoc ? myTriangul->Nodes().Value (aSegmStartIdx).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aSegmStartIdx);
gp_Pnt aSegmEnd = hasInitLoc ? myTriangul->Nodes().Value (aSegmEndIdx).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aSegmEndIdx);
gp_Pnt aSegmStart = myTriangul->Nodes().Value (aSegmStartIdx);
gp_Pnt aSegmEnd = myTriangul->Nodes().Value (aSegmEndIdx);
anEdgePnts->SetValue (1, aSegmStart);
anEdgePnts->SetValue (2, aSegmEnd);
Standard_Boolean isMatched = theMgr.Overlaps (anEdgePnts, Select3D_TOS_BOUNDARY, theMatchDepth);
@@ -286,12 +279,9 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
Standard_Integer aNode1, aNode2, aNode3;
aTriangles (aPrimitiveIdx + 1).Get (aNode1, aNode2, aNode3);
gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode1);
gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode3);
gp_Pnt aPnt1 = myTriangul->Nodes().Value (aNode1);
gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, Select3D_TOS_INTERIOR, theMatchDepth);
}
}
@@ -303,8 +293,6 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
const Standard_Integer theElemIdx)
{
Standard_Real aDummy;
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
if (mySensType == Select3D_TOS_BOUNDARY)
@@ -312,13 +300,7 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
gp_Pnt aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1));
gp_Pnt aSegmPnt2 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 2));
if (HasInitLocation()) // Note: Should be removed (by transforming frustum)
{
aSegmPnt1.Transform (myInitLocation.Transformation());
aSegmPnt2.Transform (myInitLocation.Transformation());
}
return theMgr.Overlaps (aSegmPnt1, aDummy) && theMgr.Overlaps (aSegmPnt2, aDummy);
return theMgr.Overlaps (aSegmPnt1) && theMgr.Overlaps (aSegmPnt2);
}
else
{
@@ -332,16 +314,9 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
if (HasInitLocation()) // Note: Should be removed (by transforming frustum)
{
aPnt1.Transform (myInitLocation.Transformation());
aPnt2.Transform (myInitLocation.Transformation());
aPnt3.Transform (myInitLocation.Transformation());
}
return theMgr.Overlaps (aPnt1, aDummy)
&& theMgr.Overlaps (aPnt2, aDummy)
&& theMgr.Overlaps (aPnt3, aDummy);
return theMgr.Overlaps (aPnt1)
&& theMgr.Overlaps (aPnt2)
&& theMgr.Overlaps (aPnt3);
}
}
@@ -388,7 +363,7 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::applyTransformation()
gp_Pnt aVertex = gp_Pnt (aX == 0 ? myBndBox.CornerMin().x() : myBndBox.CornerMax().x(),
aY == 0 ? myBndBox.CornerMin().y() : myBndBox.CornerMax().y(),
aZ == 0 ? myBndBox.CornerMin().z() : myBndBox.CornerMax().z());
aVertex.Transform (myInitLocation);
aVertex.Transform (myInitLocation.Transformation());
aBndBox.Add (Select3D_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
}
}
@@ -429,7 +404,7 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::BoundingBox()
//=======================================================================
gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const
{
return HasInitLocation() ? myCDG3D.Transformed (myInitLocation) : myCDG3D;
return myCDG3D;
}
//=======================================================================
@@ -439,4 +414,22 @@ gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const
Standard_Integer Select3D_SensitiveTriangulation::NbSubElements()
{
return myTriangul->Nodes().Length();
}
}
//=======================================================================
//function : HasInitLocation
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
{
return !myInitLocation.IsIdentity();
}
//=======================================================================
//function : InvInitLocation
//purpose :
//=======================================================================
gp_Trsf Select3D_SensitiveTriangulation::InvInitLocation() const
{
return myInvInitLocation;
}

View File

@@ -78,10 +78,6 @@ public:
const Handle(Poly_Triangulation)& Triangulation() const;
Standard_Boolean HasInitLocation() const;
const TopLoc_Location& GetInitLocation() const;
//! Returns the length of array of triangles or edges
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
@@ -105,6 +101,15 @@ public:
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns true if the shape corresponding to the entity has init location
Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
//! Returns inversed location transformation matrix if the shape corresponding
//! to this entity has init location set. Otherwise, returns identity matrix.
Standard_EXPORT virtual gp_Trsf InvInitLocation() const Standard_OVERRIDE;
inline const TopLoc_Location& GetInitLocation() const;
public:
DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
@@ -129,20 +134,18 @@ private:
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
const Standard_Integer theElemIdx) Standard_OVERRIDE;
public:
Standard_Real myBVHBuildTime;
private:
Handle(Poly_Triangulation) myTriangul;
TopLoc_Location myInitLocation;
gp_Pnt myCDG3D; //!< Center of the whole triangulation
TopLoc_Location myInitLocation;
gp_Pnt myCDG3D; //!< Center of the whole triangulation
Handle(TColStd_HArray1OfInteger) myFreeEdges;
Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior
Standard_Integer myDetectedTr;
Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type
Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior
Standard_Integer myDetectedTr;
Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type
Handle(TColStd_HArray1OfInteger) myBVHPrimIndexes; //!< Indexes of edges or triangles for BVH build
mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
gp_Trsf myInvInitLocation;
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)

View File

@@ -23,15 +23,6 @@ inline const Handle(Poly_Triangulation)& Select3D_SensitiveTriangulation::Triang
return myTriangul;
}
//=======================================================================
//function : HasInitLocation
//purpose :
//=======================================================================
inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
{
return !myInitLocation.IsIdentity();
}
//=======================================================================
//function : GetInitLocation
//purpose :