1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-03 14:10:33 +03:00

0026719: Visualization - cannot pick zoom persistent object

- trsf matrix scale factor is now taken into account in depth and distance calculation in selection;
- fixed trsf matrix application error in frustum cache in SelectMgr_ViewerSelector;
- fixed multiple errors in vstate output;
- test cases for issue #26719.
This commit is contained in:
vpa
2015-10-08 14:02:39 +03:00
committed by bugmaster
parent 24a886979e
commit 7479f6433c
6 changed files with 202 additions and 24 deletions

View File

@@ -71,7 +71,7 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd);
gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTc;
theDepth = myNearPickedPnt.Distance (aClosestPnt);
theDepth = myNearPickedPnt.Distance (aClosestPnt) * myScale;
}
// =======================================================================
@@ -109,7 +109,7 @@ void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const gp_Vec& thePl
}
gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + anU * aParam;
theDepth = myNearPickedPnt.Distance (aClosestPnt);
theDepth = myNearPickedPnt.Distance (aClosestPnt) * myScale;
}
namespace
@@ -275,6 +275,8 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint)
// compute vertices projections onto frustum normals and
// {i, j, k} vectors and store them to corresponding class fields
cacheVertexProjections (this);
myScale = 1.0;
}
// =======================================================================
@@ -301,6 +303,8 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d& theMinPnt,
// compute vertices projections onto frustum normals and
// {i, j, k} vectors and store them to corresponding class fields
cacheVertexProjections (this);
myScale = 1.0;
}
// =======================================================================
@@ -382,6 +386,8 @@ NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::ScaleAnd
aRes->myEdgeDirs[4] = aRes->myVertices[0].XYZ() - aRes->myVertices[1].XYZ();
// RightUpper
aRes->myEdgeDirs[5] = aRes->myVertices[4].XYZ() - aRes->myVertices[5].XYZ();
aRes->myScale = 1.0 / theTrsf.ScaleFactor();
}
// compute frustum normals
@@ -441,7 +447,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt,
gp_Pnt aDetectedPnt =
myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * (aV.Dot (myViewRayDir.XYZ()) / myViewRayDir.Dot (myViewRayDir));
theDepth = aDetectedPnt.Distance (myNearPickedPnt);
theDepth = aDetectedPnt.Distance (myNearPickedPnt) * myScale;
return Standard_True;
}
@@ -567,7 +573,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
// handle the case when triangle normal and selecting frustum direction are orthogonal: for this case, overlap
// is detected correctly, and distance to triangle's plane can be measured as distance to its arbitrary vertex.
const gp_XYZ aDiff = myNearPickedPnt.XYZ() - thePnt1.XYZ();
theDepth = aTriangleNormal.Dot (aDiff);
theDepth = aTriangleNormal.Dot (aDiff) * myScale;
return Standard_True;
}
@@ -585,7 +591,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
if (isInterior)
{
gp_Pnt aDetectedPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTime;
theDepth = myNearPickedPnt.Distance (aDetectedPnt);
theDepth = myNearPickedPnt.Distance (aDetectedPnt) * myScale;
return Standard_True;
}
@@ -617,7 +623,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
// =======================================================================
Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt& theCOG)
{
return theCOG.Distance (myNearPickedPnt);
return theCOG.Distance (myNearPickedPnt) * myScale;
}
// =======================================================================

View File

@@ -33,7 +33,7 @@ class SelectMgr_RectangularFrustum : public SelectMgr_Frustum<4>
{
public:
SelectMgr_RectangularFrustum() {};
SelectMgr_RectangularFrustum() : myScale (1.0) {};
//! Builds volume according to the point and given pixel tolerance
Standard_EXPORT virtual void Build (const gp_Pnt2d& thePoint) Standard_OVERRIDE;
@@ -138,6 +138,7 @@ private:
gp_Pnt myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
gp_Vec myViewRayDir;
gp_Pnt2d myMousePos; //!< Mouse coordinates
Standard_Real myScale; //!< Scale factor of applied transformation, if there was any
};
#endif // _SelectMgr_RectangularFrustum_HeaderFile

View File

@@ -269,27 +269,26 @@ void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_Sensiti
SelectMgr_FrustumCache& theCachedMgrs,
SelectMgr_SelectingVolumeManager& theResMgr)
{
Standard_Integer aScale = 1;
const Standard_Boolean toScale = isToScaleFrustum (theEnt);
if (toScale)
Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
const gp_Trsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
const Standard_Boolean toScale = aScale != 1;
const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
if (toScale && toTransform)
{
aScale = sensitivity (theEnt);
}
if (theEnt->HasInitLocation())
{
theResMgr =
mySelectingVolumeMgr.ScaleAndTransform (aScale, theEnt->InvInitLocation() * theInvTrsf);
theResMgr = mySelectingVolumeMgr.ScaleAndTransform (aScale, aTrsfMtr);
}
else if (toScale)
{
if (!theCachedMgrs.IsBound (aScale))
{
theCachedMgrs.Bind (aScale,
mySelectingVolumeMgr.ScaleAndTransform(aScale, theInvTrsf));
theCachedMgrs.Bind (aScale, mySelectingVolumeMgr.ScaleAndTransform (aScale, gp_Trsf()));
}
theResMgr = theCachedMgrs.Find (aScale);
}
else if (toTransform)
{
theResMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTrsfMtr);
}
}
//=======================================================================

View File

@@ -4428,17 +4428,42 @@ static Standard_Integer VState (Draw_Interpretor& theDI,
{
theDI << "Detected entities:\n";
Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->HasOpenedContext() ? aCtx->LocalSelector() : aCtx->MainSelector();
SelectMgr_SelectingVolumeManager aMgr = aSelector->GetManager();
for (aSelector->InitDetected(); aSelector->MoreDetected(); aSelector->NextDetected())
{
const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity();
Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
SelectMgr_SelectingVolumeManager aMgr =
anObj->HasTransformation() ? aSelector->GetManager().ScaleAndTransform (1, anObj->InversedTransformation())
: aSelector->GetManager();
gp_Trsf anInvTrsf;
if (anObj->TransformPersistence().Flags)
{
const Graphic3d_Mat4d& aProjection = aMgr.ProjectionMatrix();
const Graphic3d_Mat4d& aWorldView = aMgr.WorldViewMatrix();
Graphic3d_Mat4d aMat = anObj->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
anInvTrsf.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
anInvTrsf.Invert();
}
if (anObj->HasTransformation())
{
anInvTrsf = anObj->InversedTransformation() * anInvTrsf;
}
if (anEntity->HasInitLocation())
{
anInvTrsf = anEntity->InvInitLocation() * anInvTrsf;
}
const Standard_Integer aScale = anEntity->SensitivityFactor() < aSelector->PixelTolerance()
? anEntity->SensitivityFactor() : 1;
const Standard_Boolean isToScaleAndTransform = anInvTrsf.Form() != gp_Identity || aScale != 1;
SelectMgr_SelectingVolumeManager anEntMgr =
isToScaleAndTransform ? aMgr.ScaleAndTransform (aScale, anInvTrsf)
: aMgr;
SelectBasics_PickResult aResult;
anEntity->Matches (aMgr, aResult);
gp_Pnt aDetectedPnt = aMgr.DetectedPoint (aResult.Depth());
anEntity->Matches (anEntMgr, aResult);
gp_Pnt aDetectedPnt = anInvTrsf.Form() == gp_Identity ?
anEntMgr.DetectedPoint (aResult.Depth()) : anEntMgr.DetectedPoint (aResult.Depth()).Transformed (anInvTrsf.Inverted());
TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
aName.LeftJustify (20, ' ');