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

Compare commits

...

7 Commits

Author SHA1 Message Date
mzernova
a425f3ade1 # Check circles nb 2024-09-06 11:50:36 +01:00
mzernova
9b6c641484 # fix cone with holes 2024-09-06 11:50:35 +01:00
Vitaut Tryputsin
8c3471161b #fix cone 2024-09-06 11:50:35 +01:00
mzernova
cacbe65d83 # Add test for cone 2024-09-06 11:50:34 +01:00
mzernova
603a391e9c # Fix cone 2024-09-06 11:50:34 +01:00
mzernova
780f2278a1 # Remarks from @vtryputs 2024-09-06 11:50:33 +01:00
mzernova
75a1e08b63 0033664: Visualization - Selection does not work for simple shape
Fixed direction calculation for Select3D_SensitiveCylinder created from Geom_CylindricalSurface
2024-09-06 11:50:33 +01:00
3 changed files with 93 additions and 54 deletions

View File

@@ -562,54 +562,33 @@ void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape
}
//=======================================================================
//function : getCylinderHeight
//function : getCylinderCircles
//purpose :
//=======================================================================
static Standard_Real getCylinderHeight (const Handle(Poly_Triangulation)& theTriangulation,
const TopLoc_Location& theLoc)
static NCollection_Sequence<gp_Circ> getCylinderCircles (const TopoDS_Face& theHollowCylinder)
{
Bnd_Box aBox;
gp_Trsf aScaleTrsf;
aScaleTrsf.SetScaleFactor (theLoc.Transformation().ScaleFactor());
theTriangulation->MinMax (aBox, aScaleTrsf);
return aBox.CornerMax().Z() - aBox.CornerMin().Z();
}
//=======================================================================
//function : isCylinderOrCone
//purpose :
//=======================================================================
static Standard_Boolean isCylinderOrCone (const TopoDS_Face& theHollowCylinder, const gp_Pnt& theLocation, gp_Dir& theDirection)
{
Standard_Integer aCirclesNb = 0;
Standard_Boolean isCylinder = Standard_False;
gp_Pnt aPos;
NCollection_Sequence<gp_Circ> aCircles;
Standard_Integer aLinesNb = 0;
TopExp_Explorer anEdgeExp;
for (anEdgeExp.Init (theHollowCylinder, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeExp.Current());
BRepAdaptor_Curve anAdaptor (anEdge);
aLinesNb++;
if (anAdaptor.GetType() == GeomAbs_Circle
&& BRep_Tool::IsClosed (anEdge))
{
aCirclesNb++;
isCylinder = Standard_True;
if (aCirclesNb == 2)
{
// Reverse the direction of the cylinder, relevant if the cylinder was created as a prism
if (aPos.IsEqual (theLocation, Precision::Confusion()))
{
theDirection.Reverse();
}
return Standard_True;
}
aPos = anAdaptor.Circle().Location().XYZ();
aCircles.Append (anAdaptor.Circle());
}
else if (anAdaptor.GetType() != GeomAbs_Line || aLinesNb > 4)
{
return NCollection_Sequence<gp_Circ>();
}
}
return isCylinder;
return aCircles;
}
//=======================================================================
@@ -658,29 +637,32 @@ Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_
}
else if (Handle(Geom_ConicalSurface) aGeomCone = Handle(Geom_ConicalSurface)::DownCast (aSurf))
{
gp_Dir aDummyDir;
if (isCylinderOrCone (theFace, gp_Pnt(), aDummyDir))
NCollection_Sequence<gp_Circ> aCircles = getCylinderCircles (theFace);
if (aCircles.Size() > 0 && aCircles.Size() < 3)
{
const gp_Cone aCone = BRepAdaptor_Surface (theFace).Cone();
const Standard_Real aRad1 = aCone.RefRadius();
const Standard_Real aHeight = getCylinderHeight (aTriangulation, aLoc);
gp_Trsf aTrsf;
aTrsf.SetTransformation (aCone.Position(), gp::XOY());
Standard_Real aRad1;
Standard_Real aRad2;
if (aRad1 == 0.0)
Standard_Real aHeight;
if (aCircles.Size() == 1)
{
aRad2 = Tan (aCone.SemiAngle()) * aHeight;
aRad1 = 0.0;
aRad2 = aCircles.First().Radius();
aHeight = aRad2 * Tan (aCone.SemiAngle());
aTrsf.SetTransformation (aCone.Position(), gp::XOY());
}
else
{
const Standard_Real aTriangleHeight = (aCone.SemiAngle() > 0.0)
? aRad1 / Tan (aCone.SemiAngle())
: aRad1 / Tan (Abs (aCone.SemiAngle())) - aHeight;
aRad2 = (aCone.SemiAngle() > 0.0)
? aRad1 * (aTriangleHeight + aHeight) / aTriangleHeight
: aRad1 * aTriangleHeight / (aTriangleHeight + aHeight);
aHeight = aCircles.First().Location().Distance (aCircles.Last().Location());
const gp_Circ& aFirstCircle = aCircles.First();
const gp_Circ& aLastCircle = aCircles.Last();
const gp_Circ& aSmallerCircle = (aFirstCircle.Radius() < aLastCircle.Radius()) ? aFirstCircle : aLastCircle;
const gp_Circ& aLargerCircle = (aFirstCircle.Radius() > aLastCircle.Radius()) ? aFirstCircle : aLastCircle;
aRad1 = aSmallerCircle.Radius();
aRad2 = aLargerCircle.Radius();
aTrsf.SetTranslationPart (aSmallerCircle.Location().XYZ());
}
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad1, aRad2, aHeight, aTrsf, true);
@@ -690,18 +672,18 @@ Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_
}
else if (Handle(Geom_CylindricalSurface) aGeomCyl = Handle(Geom_CylindricalSurface)::DownCast (aSurf))
{
const gp_Cylinder aCyl = BRepAdaptor_Surface (theFace).Cylinder();
gp_Ax3 aPos = aCyl.Position();
gp_Dir aDirection = aPos.Direction();
if (isCylinderOrCone (theFace, aPos.Location(), aDirection))
NCollection_Sequence<gp_Circ> aCircles = getCylinderCircles (theFace);
if (aCircles.Size() == 2)
{
const gp_Cylinder aCyl = BRepAdaptor_Surface (theFace).Cylinder();
const Standard_Real aRad = aCyl.Radius();
const Standard_Real aHeight = getCylinderHeight (aTriangulation, aLoc);
const gp_Pnt aPos = aCircles.First().Location();
const gp_Dir aDirection (aCircles.Last().Location().XYZ() - aPos.XYZ());
const Standard_Real aHeight = aPos.Distance (aCircles.Last().Location());
gp_Trsf aTrsf;
aPos.SetDirection (aDirection);
aTrsf.SetTransformation (aPos, gp::XOY());
aTrsf.SetTransformation (gp_Ax3 (aPos, aDirection), gp::XOY());
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad, aRad, aHeight, aTrsf, true);
theSensitiveList.Append (aSensSCyl);

21
tests/v3d/bugs/bug33664_1 Normal file
View File

@@ -0,0 +1,21 @@
puts "============"
puts "0033664: Visualization - Selection does not work for simple shape"
puts "============"
puts ""
pload MODELING VISUALIZATION
vclear
vinit View1
restore [locate_data_file cylinder_surface.brep] b
vdisplay -dispMode 1 b
vfit
vsensdis
vselect 200 200
if {[vnbselected] != "1"} {
puts "ERROR: wrong sensitive area"
}
vselect 0 0
vdump $::imagedir/${::casename}_cylinder.png

36
tests/v3d/bugs/bug33664_2 Normal file
View File

@@ -0,0 +1,36 @@
puts "============"
puts "0033664: Visualization - Selection does not work for simple shape"
puts "============"
puts ""
pload MODELING VISUALIZATION
vclear
vinit View1
pcone c1 50 100 100
ttranslate c1 100 0 100
explode c1
explode c1_1
pcone c2 100 50 100
ttranslate c2 -100 0 100
explode c2
explode c2_1
pcone c3 0 100 100
ttranslate c3 100 0 -100
explode c3
explode c3_1
pcone c4 100 0 100
ttranslate c4 -100 0 -100
explode c4
explode c4_1
vdisplay c1_1_1 c2_1_1 c3_1_1 c4_1_1 -dispmode 1
vsensdis
vfront
vfit
vdump $::imagedir/${::casename}_cone.png