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:
@@ -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;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -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, ' ');
|
||||
|
Reference in New Issue
Block a user