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

0032652: Visualization - Select3D_SensitiveCylinder returns wrong 3D point on transformed shape

SelectMgr_RectangularFrustum::OverlapsCylinder() - added missing 3D point transformation.
StdSelect_BRepSelectionTool::ComputeSensitive() - fixed cylinder height computation on TopoDS_Shape with scale transformation.
SelectMgr_AxisIntersector::OverlapsCylinder(),::OverlapsSphere() - added missing computations of surface normal.
This commit is contained in:
kgv
2021-11-09 15:17:43 +03:00
parent 642ddd1253
commit 660a8938a3
22 changed files with 209 additions and 21 deletions

View File

@@ -543,7 +543,11 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsSphere (const gp_Pnt& theCen
return Standard_False;
}
const gp_Pnt aPntOnSphere (myAxis.Location().XYZ() + myAxis.Direction().XYZ() * aDepth);
const gp_Vec aNormal (aPntOnSphere.XYZ() - theCenter.XYZ());
thePickResult.SetDepth (aDepth);
thePickResult.SetPickedPoint (aPntOnSphere);
thePickResult.SetSurfaceNormal (aNormal);
return Standard_True;
}
@@ -576,7 +580,22 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsCylinder (const Standard_Rea
{
return false;
}
const gp_Pnt aPntOnCylinder = aLoc.XYZ() + aRayDir.XYZ() * aDepth;
thePickResult.SetDepth (aDepth);
thePickResult.SetPickedPoint (aPntOnCylinder.Transformed (theTrsf));
if (Abs (aPntOnCylinder.Z()) < Precision::Confusion())
{
thePickResult.SetSurfaceNormal (-gp::DZ().Transformed (theTrsf));
}
else if (Abs (aPntOnCylinder.Z() - theHeight) < Precision::Confusion())
{
thePickResult.SetSurfaceNormal (gp::DZ().Transformed (theTrsf));
}
else
{
thePickResult.SetSurfaceNormal (gp_Vec (aPntOnCylinder.X(), aPntOnCylinder.Y(), 0.0).Transformed (theTrsf));
}
return true;
}

View File

@@ -753,20 +753,24 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_
{
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point || mySelectionType == SelectMgr_SelectionType_Box,
"Error! SelectMgr_RectangularFrustum::Overlaps() should be called after selection frustum initialization");
Standard_Real aTimeEnter = 0.0, aTimeLeave = 0.0;
Standard_Real aTimes[2] = { 0.0, 0.0 };
const gp_Trsf aTrsfInv = theTrsf.Inverted();
const gp_Pnt aLoc = myNearPickedPnt.Transformed (aTrsfInv);
const gp_Dir aRayDir = myViewRayDir .Transformed (aTrsfInv);
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir, aTimeEnter, aTimeLeave))
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir, aTimes[0], aTimes[1]))
{
return Standard_False;
}
thePickResult.SetDepth (aTimeEnter * myScale);
Standard_Integer aResTime = 0;
thePickResult.SetDepth (aTimes[aResTime] * myScale);
if (theClipRange.IsClipped (thePickResult.Depth()))
{
thePickResult.SetDepth (aTimeLeave * myScale);
aResTime = 1;
thePickResult.SetDepth (aTimes[aResTime] * myScale);
}
const gp_Pnt aPntOnCylinder (aLoc.XYZ() + aRayDir.XYZ() * thePickResult.Depth());
const gp_Pnt aPntOnCylinder = aLoc.XYZ() + aRayDir.XYZ() * aTimes[aResTime];
if (Abs (aPntOnCylinder.Z()) < Precision::Confusion())
{
thePickResult.SetSurfaceNormal (-gp::DZ().Transformed (theTrsf));
@@ -779,7 +783,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_
{
thePickResult.SetSurfaceNormal (gp_Vec (aPntOnCylinder.X(), aPntOnCylinder.Y(), 0.0).Transformed (theTrsf));
}
thePickResult.SetPickedPoint (aPntOnCylinder);
thePickResult.SetPickedPoint (aPntOnCylinder.Transformed (theTrsf));
return !theClipRange.IsClipped (thePickResult.Depth());
}

View File

@@ -280,11 +280,11 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
&TopoDS::Face (aSubfacesMap.FindKey (2))
};
TopLoc_Location aLocSurf;
TopLoc_Location aLocSurf[2];
const Handle(Geom_Surface)* aSurfaces[2] =
{
&BRep_Tool::Surface (*aFaces[0], aLocSurf),
&BRep_Tool::Surface (*aFaces[1], aLocSurf)
&BRep_Tool::Surface (*aFaces[0], aLocSurf[0]),
&BRep_Tool::Surface (*aFaces[1], aLocSurf[1])
};
Standard_Integer aConIndex = 0;
@@ -308,7 +308,7 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
const Standard_Real aRad1 = aCone.RefRadius();
const Standard_Real aHeight = (aRad1 != 0.0)
? aRad1 / Abs (Tan (aCone.SemiAngle()))
: aCone.Location().Distance (aGeomPln->Location());
: aCone.Location().Distance (aGeomPln->Location().Transformed (aLocSurf[aConIndex == 0 ? 1 : 0]));
const Standard_Real aRad2 = (aRad1 != 0.0) ? 0.0 : Tan (aCone.SemiAngle()) * aHeight;
gp_Trsf aTrsf;
aTrsf.SetTransformation (aCone.Position(), gp_Ax3());
@@ -326,18 +326,19 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
&TopoDS::Face (aSubfacesMap.FindKey (3))
};
TopLoc_Location aLocSurf;
TopLoc_Location aLocSurf[3];
const Handle(Geom_Surface)* aSurfaces[3] =
{
&BRep_Tool::Surface (*aFaces[0], aLocSurf),
&BRep_Tool::Surface (*aFaces[1], aLocSurf),
&BRep_Tool::Surface (*aFaces[2], aLocSurf)
&BRep_Tool::Surface (*aFaces[0], aLocSurf[0]),
&BRep_Tool::Surface (*aFaces[1], aLocSurf[1]),
&BRep_Tool::Surface (*aFaces[2], aLocSurf[2])
};
Standard_Integer aConIndex = -1, aNbPlanes = 0;
Handle(Geom_ConicalSurface) aGeomCone;
Handle(Geom_CylindricalSurface) aGeomCyl;
Handle(Geom_Plane) aGeomPlanes[2];
const TopLoc_Location* aGeomPlanesLoc[2];
for (Standard_Integer aSurfIter = 0; aSurfIter < 3; ++aSurfIter)
{
const Handle(Geom_Surface)& aSurf = *aSurfaces[aSurfIter];
@@ -361,6 +362,7 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
aGeomPlanes[aNbPlanes] = Handle(Geom_Plane)::DownCast (aSurf);
if (!aGeomPlanes[aNbPlanes].IsNull())
{
aGeomPlanesLoc[aNbPlanes] = &aLocSurf[aSurfIter];
++aNbPlanes;
}
}
@@ -375,7 +377,8 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
{
const gp_Cone aCone = BRepAdaptor_Surface (*aFaces[aConIndex]).Cone();
const Standard_Real aRad1 = aCone.RefRadius();
const Standard_Real aHeight = aGeomPlanes[0]->Location().Distance (aGeomPlanes[1]->Location());
const Standard_Real aHeight = aGeomPlanes[0]->Location().Transformed (*aGeomPlanesLoc[0])
.Distance (aGeomPlanes[1]->Location().Transformed (*aGeomPlanesLoc[1]));
gp_Trsf aTrsf;
aTrsf.SetTransformation (aCone.Position(), gp_Ax3());
const Standard_Real aTriangleHeight = (aCone.SemiAngle() > 0.0)
@@ -398,7 +401,8 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
{
const gp_Cylinder aCyl = BRepAdaptor_Surface (*aFaces[aConIndex]).Cylinder();
const Standard_Real aRad = aCyl.Radius();
const Standard_Real aHeight = aGeomPlanes[0]->Location().Distance (aGeomPlanes[1]->Location());
const Standard_Real aHeight = aGeomPlanes[0]->Location().Transformed (*aGeomPlanesLoc[0])
.Distance (aGeomPlanes[1]->Location().Transformed (*aGeomPlanesLoc[1]));
gp_Trsf aTrsf;
aTrsf.SetTransformation (aCyl.Position(), gp_Ax3());
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad, aRad, aHeight, aTrsf);
@@ -410,7 +414,7 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex)
{
ComputeSensitive (aSubfacesMap (aShIndex), theOwner,
ComputeSensitive (aSubfacesMap.FindKey (aShIndex), theOwner,
theSelection,
theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
}