diff --git a/src/Select3D/Select3D_SensitiveCylinder.cxx b/src/Select3D/Select3D_SensitiveCylinder.cxx index 62fe013b25..6c2ebf181e 100644 --- a/src/Select3D/Select3D_SensitiveCylinder.cxx +++ b/src/Select3D/Select3D_SensitiveCylinder.cxx @@ -81,17 +81,14 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveCylinder::GetConnected() Select3D_BndBox3d Select3D_SensitiveCylinder::BoundingBox() { Standard_Real aMaxRad = Max (myBottomRadius, myTopRadius); - gp_Pnt aCenterBottom (0, 0, 0); - gp_Pnt aCenterTop (0, 0, myHeight); - aCenterBottom.Transform (myTrsf); - aCenterTop.Transform (myTrsf); - const SelectMgr_Vec3 aMinPnt (Min (aCenterBottom.X(), aCenterTop.X()) - aMaxRad, - Min (aCenterBottom.Y(), aCenterTop.Y()) - aMaxRad, - Min (aCenterBottom.Z(), aCenterTop.Z()) - aMaxRad); - const SelectMgr_Vec3 aMaxPnt (Max (aCenterBottom.X(), aCenterTop.X()) + aMaxRad, - Max (aCenterBottom.Y(), aCenterTop.Y()) + aMaxRad, - Max (aCenterBottom.Z(), aCenterTop.Z()) + aMaxRad); - return Select3D_BndBox3d (aMinPnt, aMaxPnt); + Graphic3d_Mat4d aTrsf; + myTrsf.GetMat4 (aTrsf); + + Select3D_BndBox3d aBox (SelectMgr_Vec3 (-aMaxRad, -aMaxRad, 0), + SelectMgr_Vec3 (aMaxRad, aMaxRad, myHeight)); + aBox.Transform (aTrsf); + + return aBox; } //================================================== diff --git a/src/Select3D/Select3D_SensitiveCylinder.hxx b/src/Select3D/Select3D_SensitiveCylinder.hxx index 533341ee54..7a963e224a 100644 --- a/src/Select3D/Select3D_SensitiveCylinder.hxx +++ b/src/Select3D/Select3D_SensitiveCylinder.hxx @@ -54,6 +54,18 @@ public: //! Returns center of the cylinder with transformation applied Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; + //! Returns cylinder transformation + const gp_Trsf& Transformation() const { return myTrsf; } + + //! Returns cylinder top radius + Standard_Real TopRadius() const { return myTopRadius; } + + //! Returns cylinder bottom radius + Standard_Real BottomRadius() const { return myBottomRadius; } + + //! Returns cylinder height + Standard_Real Height() const { return myHeight; } + protected: gp_Trsf myTrsf; //!< cylinder transformation to apply Standard_Real myBottomRadius; //!< cylinder bottom radius diff --git a/src/SelectMgr/SelectMgr.cxx b/src/SelectMgr/SelectMgr.cxx index a6134b4508..b0999fae33 100644 --- a/src/SelectMgr/SelectMgr.cxx +++ b/src/SelectMgr/SelectMgr.cxx @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +132,43 @@ namespace theSeqLines.Append (aPoints); } } + + //! Fill in cylinder polylines. + static void addCylinder (Prs3d_NListOfSequenceOfPnt& theSeqLines, + const Handle(Select3D_SensitiveCylinder)& theSensCyl) + { + Handle(TColgp_HSequenceOfPnt) aVertLines[2]; + aVertLines[0] = new TColgp_HSequenceOfPnt(); + aVertLines[1] = new TColgp_HSequenceOfPnt(); + const gp_Trsf& aTrsf = theSensCyl->Transformation(); + const Standard_Real aHeight = theSensCyl->Height(); + const Standard_Real anUStep = 0.1; + + for (int aCircNum = 0; aCircNum < 3; aCircNum++) + { + Standard_Real aRadius = 0.5 * (2 - aCircNum) * theSensCyl->BottomRadius() + + 0.5 * aCircNum * theSensCyl->TopRadius(); + Geom_Circle aGeom (gp_Ax2(), aRadius); + Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt(); + gp_XYZ aVec (0, 0, aHeight * 0.5 * aCircNum); + + if (aCircNum != 1) + { + aVertLines[0]->Append (gp_Pnt(aGeom.Value (0).Coord() + aVec).Transformed (aTrsf)); + aVertLines[1]->Append (gp_Pnt(aGeom.Value (M_PI).Coord() + aVec).Transformed (aTrsf)); + } + + for (Standard_Real anU = 0.0f; anU < (2.0 * M_PI + anUStep); anU += anUStep) + { + gp_Pnt aCircPnt = aGeom.Value (anU).Coord() + aVec; + aCircPnt.Transform (aTrsf); + aPoints->Append (aCircPnt); + } + theSeqLines.Append (aPoints); + } + theSeqLines.Append (aVertLines[0]); + theSeqLines.Append (aVertLines[1]); + } } //======================================================================= @@ -152,6 +191,10 @@ void SelectMgr::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& thePrs, { addBoundingBox (aSeqLines, aSensBox, theLoc); } + else if (Handle(Select3D_SensitiveCylinder) aSensCyl = Handle(Select3D_SensitiveCylinder)::DownCast (anEnt)) + { + addCylinder (aSeqLines, aSensCyl); + } else if (Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(anEnt)) { Handle(TColgp_HArray1OfPnt) aSensPnts; diff --git a/src/StdSelect/StdSelect_BRepSelectionTool.cxx b/src/StdSelect/StdSelect_BRepSelectionTool.cxx index 630d328d91..36e5ce9fca 100644 --- a/src/StdSelect/StdSelect_BRepSelectionTool.cxx +++ b/src/StdSelect/StdSelect_BRepSelectionTool.cxx @@ -390,15 +390,23 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape { if (!aGeomPlanes[0].IsNull() && !aGeomPlanes[1].IsNull() - && aGeomPlanes[0]->Position().Direction().IsEqual (aGeomCyl->Position().Direction(), Precision::Angular()) - && aGeomPlanes[1]->Position().Direction().IsEqual (aGeomCyl->Position().Direction(), Precision::Angular())) + && aGeomPlanes[0]->Position().Direction().IsParallel (aGeomCyl->Position().Direction(), Precision::Angular()) + && aGeomPlanes[1]->Position().Direction().IsParallel (aGeomCyl->Position().Direction(), Precision::Angular())) { const gp_Cylinder aCyl = BRepAdaptor_Surface (*aFaces[aConIndex]).Cylinder(); const Standard_Real aRad = aCyl.Radius(); 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()); + gp_Ax3 aPos = aCyl.Position(); + if (aGeomPlanes[0]->Position().IsCoplanar (aGeomPlanes[1]->Position(), Precision::Angular(), Precision::Angular())) + { + // cylinders created as a prism have an inverse vector of the cylindrical surface + aPos.SetDirection (aPos.Direction().Reversed()); + } + aTrsf.SetTransformation (aPos, gp_Ax3()); + Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad, aRad, aHeight, aTrsf); theSelection->Add (aSensSCyl); break; diff --git a/tests/vselect/bugs/bug33084 b/tests/vselect/bugs/bug33084 new file mode 100644 index 0000000000..c047df260a --- /dev/null +++ b/tests/vselect/bugs/bug33084 @@ -0,0 +1,26 @@ +puts "=============" +puts "0033084: Visualization - Cylindrical prism is selectable only by its base when extruded in some directions" +puts "=============" + +pload MODELING VISUALIZATION +profile p1 c 1 360 ww +mkplane f p1 +prism pr1 f 0 0 2 +prism pr2 f 0 0 -2 +ttranslate pr1 1 1 1 +ttranslate pr2 -1 -1 -1 + +vinit View1 +vclear +vaxo +vdisplay -dispmode 1 pr1 pr2 +vfit +vsensdis + +vdump $imagedir/${casename}_prism_sensitive_prs.png + +vmoveto 130 330 +if { ![string match "*Select3D_SensitiveCylinder*" [vstate -entities]] } { puts "Error: cylinder should be detected" } + +vmoveto 270 130 +if { ![string match "*Select3D_SensitiveCylinder*" [vstate -entities]] } { puts "Error: cylinder should be detected" }