0031548: Visualization, SelectBasics_PickResult - include surface normal into picking...
authorkgv <kgv@opencascade.com>
Mon, 4 May 2020 22:23:41 +0000 (01:23 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 6 May 2020 16:09:53 +0000 (19:09 +0300)
SelectMgr_SortCriterion::Normal, SelectBasics_PickResult::SurfaceNormal() - added new property.
SelectMgr_RectangularFrustum::Overlaps() for triangle sets new normal property.
gp_GTrsf::GetMat4() - added conversion into NCollection_Mat4 similar to gp_Trsf::GetMat4().

src/SelectBasics/SelectBasics_PickResult.hxx
src/SelectMgr/SelectMgr_RectangularFrustum.cxx
src/SelectMgr/SelectMgr_SortCriterion.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/ViewerTest/ViewerTest.cxx
src/gp/gp_GTrsf.hxx

index 56a119b..32ab74a 100644 (file)
@@ -55,6 +55,7 @@ public:
   {
     myDepth = RealLast();
     myObjPickedPnt = gp_Pnt (RealLast(), 0.0, 0.0);
+    myNormal.SetValues (0.0f, 0.0f, 0.0f);
   }
 
   //! Return depth along picking ray.
@@ -79,10 +80,24 @@ public:
   //! Set distance to geometry center.
   void SetDistToGeomCenter (Standard_Real theDistToCenter) { myDistToCenter = theDistToCenter; }
 
+  //! Return (unnormalized) surface normal at picked point or zero vector if undefined.
+  //! WARNING! Normal is defined in local coordinate system and should be translated into World System before usage!
+  const NCollection_Vec3<float>& SurfaceNormal() const { return myNormal; }
+
+  //! Set surface normal at picked point.
+  void SetSurfaceNormal (const NCollection_Vec3<float>& theNormal) { myNormal = theNormal; }
+
+  //! Set surface normal at picked point.
+  void SetSurfaceNormal (const gp_Vec& theNormal)
+  {
+    myNormal.SetValues ((float )theNormal.X(), (float )theNormal.Y(), (float )theNormal.Z());
+  }
+
 private:
-  gp_Pnt        myObjPickedPnt; //!< User-picked selection point onto object
-  Standard_Real myDepth;        //!< Depth to detected point
-  Standard_Real myDistToCenter; //!< Distance from 3d projection user-picked selection point to entity's geometry center
+  gp_Pnt                  myObjPickedPnt; //!< User-picked selection point onto object
+  NCollection_Vec3<float> myNormal;       //!< surface normal
+  Standard_Real           myDepth;        //!< Depth to detected point
+  Standard_Real           myDistToCenter; //!< Distance from 3d projection user-picked selection point to entity's geometry center
 };
 
 #endif // _SelectBasics_PickResult_HeaderFile
index a89e7f3..c5b9f2f 100644 (file)
@@ -669,6 +669,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
       const gp_XYZ aDiff = myNearPickedPnt.XYZ() - thePnt1.XYZ();
       thePickResult.SetDepth (aTriangleNormal.Dot (aDiff) * myScale);
       thePickResult.SetPickedPoint (thePnt1);
+      thePickResult.SetSurfaceNormal (aTriangleNormal);
       return !theClipRange.IsClipped (thePickResult.Depth());
     }
 
@@ -687,6 +688,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
     {
       thePickResult.SetDepth (myNearPickedPnt.Distance (aPtOnPlane) * myScale);
       thePickResult.SetPickedPoint (aPtOnPlane);
+      thePickResult.SetSurfaceNormal (aTriangleNormal);
       return !theClipRange.IsClipped (thePickResult.Depth());
     }
 
index f7df269..a95383c 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _SelectMgr_SortCriterion_HeaderFile
 #define _SelectMgr_SortCriterion_HeaderFile
 
+#include <Graphic3d_Vec3.hxx>
 #include <Graphic3d_ZLayerId.hxx>
 #include <Precision.hxx>
 #include <Select3D_SensitiveEntity.hxx>
@@ -29,6 +30,7 @@ public:
 
   Handle(Select3D_SensitiveEntity) Entity; //!< detected entity
   gp_Pnt             Point;           //!< 3D point
+  Graphic3d_Vec3     Normal;          //!< surface normal or 0 vector if undefined
   Standard_Real      Depth;           //!< distance from the view plane to the entity
   Standard_Real      MinDist;         //!< distance from the clicked point to the entity on the view plane
   Standard_Real      Tolerance;       //!< tolerance used for selecting candidates
index 71e1f22..9ada79f 100644 (file)
@@ -76,9 +76,17 @@ void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriter
     return;
   }
 
+  bool hasNormal = false;
   if (thePickResult.HasPickedPoint())
   {
-    theCriterion.Point = thePickResult.PickedPoint();
+    theCriterion.Point  = thePickResult.PickedPoint();
+    theCriterion.Normal = thePickResult.SurfaceNormal();
+    const float aNormLen2 = theCriterion.Normal.SquareModulus();
+    if (aNormLen2 > ShortRealEpsilon())
+    {
+      hasNormal = true;
+      theCriterion.Normal *= 1.0f / sqrtf (aNormLen2);
+    }
   }
   else if (!thePickResult.IsValid())
   {
@@ -97,7 +105,15 @@ void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriter
   }
   if (anInvTrsf.Form() != gp_Identity)
   {
-    anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
+    const gp_GTrsf anInvInvTrsd = anInvTrsf.Inverted();
+    anInvInvTrsd.Transforms (theCriterion.Point.ChangeCoord());
+    if (hasNormal)
+    {
+      Graphic3d_Mat4d aMat4;
+      anInvInvTrsd.GetMat4 (aMat4);
+      const Graphic3d_Vec4d aNormRes = aMat4 * Graphic3d_Vec4d (Graphic3d_Vec3d (theCriterion.Normal), 0.0);
+      theCriterion.Normal = Graphic3d_Vec3 (aNormRes.xyz());
+    }
   }
 
   if (mySelectingVolumeMgr.Camera().IsNull())
index a3ae0d7..b96b0c9 100644 (file)
@@ -5591,11 +5591,23 @@ static Standard_Integer VState (Draw_Interpretor& theDI,
       GetMapOfAIS().Find1 (anObj, aName);
       aName.LeftJustify (20, ' ');
       char anInfoStr[512];
-      Sprintf (anInfoStr,
-               " Depth: %g Distance: %g Point: %g %g %g",
-               aPickData.Depth,
-               aPickData.MinDist,
-               aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z());
+      if (aPickData.Normal.SquareModulus() > ShortRealEpsilon())
+      {
+        Sprintf (anInfoStr,
+                 " Depth: %g Distance: %g Point: %g %g %g Normal: %g %g %g",
+                 aPickData.Depth,
+                 aPickData.MinDist,
+                 aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z(),
+                 aPickData.Normal.x(), aPickData.Normal.y(), aPickData.Normal.z());
+      }
+      else
+      {
+        Sprintf (anInfoStr,
+                 " Depth: %g Distance: %g Point: %g %g %g",
+                 aPickData.Depth,
+                 aPickData.MinDist,
+                 aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z());
+      }
       theDI << "  " << aName
             << anInfoStr
             << " (" << anEntity->DynamicType()->Name() << ")"
index 0d2414c..8a1118d 100644 (file)
@@ -244,28 +244,44 @@ public:
   
     gp_Trsf Trsf() const;
 
+  //! Convert transformation to 4x4 matrix.
+  template<class T>
+  void GetMat4 (NCollection_Mat4<T>& theMat) const
+  {
+    if (shape == gp_Identity)
+    {
+      theMat.InitIdentity();
+      return;
+    }
+
+    theMat.SetValue (0, 0, static_cast<T> (Value (1, 1)));
+    theMat.SetValue (0, 1, static_cast<T> (Value (1, 2)));
+    theMat.SetValue (0, 2, static_cast<T> (Value (1, 3)));
+    theMat.SetValue (0, 3, static_cast<T> (Value (1, 4)));
+    theMat.SetValue (1, 0, static_cast<T> (Value (2, 1)));
+    theMat.SetValue (1, 1, static_cast<T> (Value (2, 2)));
+    theMat.SetValue (1, 2, static_cast<T> (Value (2, 3)));
+    theMat.SetValue (1, 3, static_cast<T> (Value (2, 4)));
+    theMat.SetValue (2, 0, static_cast<T> (Value (3, 1)));
+    theMat.SetValue (2, 1, static_cast<T> (Value (3, 2)));
+    theMat.SetValue (2, 2, static_cast<T> (Value (3, 3)));
+    theMat.SetValue (2, 3, static_cast<T> (Value (3, 4)));
+    theMat.SetValue (3, 0, static_cast<T> (0));
+    theMat.SetValue (3, 1, static_cast<T> (0));
+    theMat.SetValue (3, 2, static_cast<T> (0));
+    theMat.SetValue (3, 3, static_cast<T> (1));
+  }
+
   //! Dumps the content of me into the stream
   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
-
-
-
-protected:
-
-
-
-
-
 private:
 
-
-
   gp_Mat matrix;
   gp_XYZ loc;
   gp_TrsfForm shape;
   Standard_Real scale;
 
-
 };