]> OCCT Git - occt.git/commitdiff
0033084: Visualization - Cylindrical prism is selectable only by its base when extrud... IR-2022-08-05
authormzernova <mzernova@opencascade.com>
Wed, 3 Aug 2022 09:46:53 +0000 (12:46 +0300)
committersmoskvin <smoskvin@opencascade.com>
Thu, 4 Aug 2022 14:50:46 +0000 (17:50 +0300)
Fixed bounding boxes for Select3D_SensitiveCylinder.

Added display of Select3D_SensitiveCylinder presentation using the "vsensdis" command.
Added test vselect/bugs/bug33084.

src/Select3D/Select3D_SensitiveCylinder.cxx
src/Select3D/Select3D_SensitiveCylinder.hxx
src/SelectMgr/SelectMgr.cxx
src/StdSelect/StdSelect_BRepSelectionTool.cxx
tests/vselect/bugs/bug33084 [new file with mode: 0644]

index 62fe013b250aa42d49102a05fd1c0861279818c1..6c2ebf181e72bd6c04e30ad8bc8aedb583a3e3ab 100644 (file)
@@ -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;
 }
 
 //==================================================
index 533341ee540706f934f3b6f3374b9acfc314230a..7a963e224aee1e51b6b32104ffbcfb5115fcf63b 100644 (file)
@@ -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
index a6134b4508174cc5f7b29f08ac9ebacefdf5d94f..b0999fae331353c2a61c90c77a2d677815362e9b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <SelectMgr.hxx>
 
+#include <Geom_Circle.hxx>
 #include <Graphic3d_ArrayOfPoints.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
 #include <Poly_Triangulation.hxx>
@@ -22,6 +23,7 @@
 #include <TColgp_HArray1OfPnt.hxx>
 #include <TColgp_SequenceOfPnt.hxx>
 #include <Select3D_SensitiveBox.hxx>
+#include <Select3D_SensitiveCylinder.hxx>
 #include <Select3D_SensitiveEntity.hxx>
 #include <Select3D_SensitiveFace.hxx>
 #include <Select3D_SensitivePoint.hxx>
@@ -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;
index 630d328d91a08b9bdba0d190c0f8b810a5039d89..36e5ce9fca0c91929e6b655634cf5d13aea59bca 100644 (file)
@@ -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 (file)
index 0000000..c047df2
--- /dev/null
@@ -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" }