]> OCCT Git - occt-copy.git/commitdiff
0027919: Visualization - support multiple transformation persistence groups within...
authornds <nds@opencascade.com>
Wed, 14 Oct 2020 07:05:46 +0000 (10:05 +0300)
committerNatalia Ermolaeva <natalia.ermolaeva@opencascade.com>
Tue, 22 Jun 2021 15:21:17 +0000 (18:21 +0300)
- transform persistence on sensitive entity

(cherry picked from commit 982029f05e86ee909ec9edce761fbf6449eea824)
(cherry picked from commit ed6e6465a49fc751c7e51a9c7cf152889839b45b)
(cherry picked from commit f48a2bb6a66254bf70c1e97e6557046000c236e0)
(cherry picked from commit 0dd795420420ae14259fa1919a5dde5b34496ee0)
(cherry picked from commit 02b4631b15d051db0280e00204f2ded538213ff5)
(cherry picked from commit d38f5ba7b963d6d2c6156c21afe2a1582c8b9a9f)
(cherry picked from commit a250533a2ec7c07c49c6652791530d261ebbb10c)
(cherry picked from commit de30c7f85b3e361915707466b17de3b846d44772)

src/Graphic3d/Graphic3d_Structure.cxx
src/Select3D/Select3D_SensitiveEntity.hxx
src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
src/SelectMgr/SelectMgr_SelectableObjectSet.hxx
src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx
src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx

index a3f1e4e4d4f5719182680758d3e79604430573bb..16a56f40240499aa07d1da00f6ee0eb8d4a911bc 100644 (file)
@@ -802,6 +802,10 @@ Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
   Graphic3d_BndBox4f aBnd;
   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
   {
+    if (!aGroupIter.Value()->TransformPersistence().IsNull())
+    {
+      continue;
+    }
     aBnd.Combine (aGroupIter.Value()->BoundingBox());
   }
   return aBnd;
index 3015a14d5b52e4970a7dd5f5a904201ac78fb554..9abc398b47701592f1b85ec5128d57e88fabfb37 100644 (file)
@@ -27,6 +27,7 @@
 #include <SelectMgr_SelectingVolumeManager.hxx>
 #include <TopLoc_Location.hxx>
 
+class Graphic3d_TransformPers;
 class SelectMgr_EntityOwner;
 
 //! Abstract framework to define 3D sensitive entities.
@@ -93,6 +94,12 @@ public:
   //! Otherwise, returns identity matrix.
   virtual gp_GTrsf InvInitLocation() const { return gp_GTrsf(); }
 
+  //! Return transformation persistence.
+  const Handle(Graphic3d_TransformPers)& TransformPersistence() const { return myTrsfPers; }
+
+  //! Set transformation persistence.
+  virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
+
   //! Dumps the content of me into the stream
   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
@@ -103,6 +110,7 @@ protected:
 protected:
 
   Handle(SelectMgr_EntityOwner) myOwnerId;
+  Handle(Graphic3d_TransformPers)  myTrsfPers;
   Standard_Integer mySFactor;
 
 };
index 15be832ffd207ffc0a0aba24067c0715e2abb412..a8bbbae11858e5350fdbd52e3daba2e615e3b1af 100644 (file)
@@ -125,15 +125,43 @@ namespace
 
         Bnd_Box aBoundingBox;
         anObject->BoundingBox (aBoundingBox);
-        if (aBoundingBox.IsVoid()
-         || anObject->TransformPersistence().IsNull())
+        if (!aBoundingBox.IsVoid()
+         && !anObject->TransformPersistence().IsNull())
+        {
+          anObject->TransformPersistence()->Apply (theCamera, theProjectionMat, theWorldViewMat, theWidth, theHeight, aBoundingBox);
+        }
+        // processing presentations with own transform persistence
+        PrsMgr_Presentations& aPresentations = anObject->Presentations();
+        for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next())
+        {
+          const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue();
+          for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Groups()); aGroupIter.More(); aGroupIter.Next())
+          {
+            if (!aGroupIter.Value()->TransformPersistence().IsNull())
+            {
+              const Graphic3d_BndBox4f& aBndBox = aGroupIter.Value()->BoundingBox();
+              if (!aBndBox.IsValid())
+              {
+                continue;
+              }
+              Bnd_Box aGroupBoundingBox;
+              aGroupBoundingBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
+                                        aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
+              aGroupIter.Value()->TransformPersistence()->Apply (theCamera, theProjectionMat, theWorldViewMat, theWidth, theHeight, aGroupBoundingBox);
+
+              const gp_Pnt aMin = aGroupBoundingBox.CornerMin();
+              const gp_Pnt aMax = aGroupBoundingBox.CornerMax();
+              aBoundingBox.Add (aGroupBoundingBox);
+            }
+          }
+        }
+
+        if (aBoundingBox.IsVoid())
         {
           myBoundings.Add (new Select3D_HBndBox3d());
         }
         else
         {
-          anObject->TransformPersistence()->Apply (theCamera, theProjectionMat, theWorldViewMat, theWidth, theHeight, aBoundingBox);
-
           const gp_Pnt aMin = aBoundingBox.CornerMin();
           const gp_Pnt aMax = aBoundingBox.CornerMax();
           myBoundings.Add (new Select3D_HBndBox3d (Select3D_Vec3 (aMin.X(), aMin.Y(), aMin.Z()),
index 2925e42b427c7ca03df55d0883809b842c0c5c94..51dea02574d294c721da947d4930f7b2ade1ee4c 100644 (file)
@@ -190,6 +190,18 @@ private:
   {
     if (theObject->TransformPersistence().IsNull())
     {
+      PrsMgr_Presentations& aPresentations = theObject->Presentations();
+      for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next())
+      {
+        const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue();
+        for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Groups()); aGroupIter.More(); aGroupIter.Next())
+        {
+          if (!aGroupIter.Value()->TransformPersistence().IsNull())
+          {
+            return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent;
+          }
+        }
+      }
       return SelectMgr_SelectableObjectSet::BVHSubset_3d;
     }
     else if (theObject->TransformPersistence()->Mode() == Graphic3d_TMF_2d)
index bad281a5e138fb97d799f8a1cbfac5c95e05f636..e9c42a42e23d1f92b476c3376990950014a2bcbe 100644 (file)
 
 #include <SelectMgr_SensitiveEntitySet.hxx>
 
+#include <Graphic3d_TransformPers.hxx>
 #include <Select3D_SensitiveEntity.hxx>
 #include <SelectMgr_SensitiveEntity.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SensitiveEntitySet, BVH_PrimitiveSet3d)
 
+class SelectMgr_AdaptorPersistent : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(SelectMgr_AdaptorPersistent, Standard_Transient)
+public:
+  SelectMgr_AdaptorPersistent(const Handle(Graphic3d_Camera)& theCamera,
+                              const Graphic3d_Mat4d& theProjectionMat,
+                              const Graphic3d_Mat4d& theWorldViewMat,
+                              const Graphic3d_WorldViewProjState& theViewState,
+                              const Standard_Integer theViewportWidth,
+                              const Standard_Integer theViewportHeight)
+    : myCamera (theCamera), myProjectionMat (theProjectionMat),
+      myWorldViewMat (theWorldViewMat), myViewState (theViewState),
+      myViewportWidth (theViewportWidth), myViewportHeight (theViewportHeight) {}
+
+  const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
+  const Graphic3d_Mat4d& ProjectionMat() const { return myProjectionMat; }
+  const Graphic3d_Mat4d& WorldViewMat() const { return myWorldViewMat; }
+  const Graphic3d_WorldViewProjState& ViewState() const { return myViewState; }
+  Standard_Integer ViewportWidth() const { return myViewportWidth; }
+  Standard_Integer ViewportHeight() const { return myViewportHeight; }
+
+private:
+  Handle(Graphic3d_Camera) myCamera;
+  Graphic3d_Mat4d myProjectionMat;
+  Graphic3d_Mat4d myWorldViewMat;
+  Graphic3d_WorldViewProjState myViewState;
+  Standard_Integer myViewportWidth;
+  Standard_Integer myViewportHeight;
+};
+
+DEFINE_STANDARD_HANDLE(SelectMgr_AdaptorPersistent, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_AdaptorPersistent, Standard_Transient)
+
 //=======================================================================
 // function : SelectMgr_SensitiveEntitySet
 // purpose  :
@@ -47,6 +81,11 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_SensitiveEntit
   {
     addOwner (theEntity->BaseSensitive()->OwnerId());
   }
+  mySensitives.Add (theEntity);
+  if (!theEntity->BaseSensitive()->TransformPersistence().IsNull())
+  {
+    myHasEntityWithPersistence = Standard_True;
+  }
   MarkDirty();
 }
 
@@ -70,6 +109,11 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_Selection)& th
     {
       addOwner (aSelEntIter.Value()->BaseSensitive()->OwnerId());
     }
+    mySensitives.Add (aSelEntIter.Value());
+    if (!aSelEntIter.Value()->BaseSensitive()->TransformPersistence().IsNull())
+    {
+      myHasEntityWithPersistence = Standard_True;
+    }
   }
   MarkDirty();
 }
@@ -96,6 +140,7 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
 
     mySensitives.RemoveLast();
     removeOwner (aSelEntIter.Value()->BaseSensitive()->OwnerId());
+    // TODO: update myHasEntityWithPersistence state, clear myAdaptorPersistent if false
   }
 
   MarkDirty();
@@ -107,7 +152,31 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
 //=======================================================================
 Select3D_BndBox3d SelectMgr_SensitiveEntitySet::Box (const Standard_Integer theIndex) const
 {
-  return GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
+  const Handle(Select3D_SensitiveEntity)& aSensitive = GetSensitiveById (theIndex)->BaseSensitive();
+  if (aSensitive->TransformPersistence().IsNull() || myAdaptorPersistent.IsNull())
+  {
+    return GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
+  }
+
+  Select3D_BndBox3d aSensitiveBndBox = GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
+  Select3D_BndBox3d aBndBoxInPersistence;
+
+  Bnd_Box aBndBox (
+    gp_Pnt (aSensitiveBndBox.CornerMin().x(), aSensitiveBndBox.CornerMin().y(), aSensitiveBndBox.CornerMin().z()),
+    gp_Pnt (aSensitiveBndBox.CornerMax().x(), aSensitiveBndBox.CornerMin().y(), aSensitiveBndBox.CornerMin().z()));
+
+  aSensitive->TransformPersistence()->Apply (
+    myAdaptorPersistent->Camera(),
+    myAdaptorPersistent->ProjectionMat(),
+    myAdaptorPersistent->WorldViewMat(),
+    myAdaptorPersistent->ViewportWidth(),
+    myAdaptorPersistent->ViewportHeight(),
+    aBndBox);
+
+  gp_Pnt aBndBoxMin = aBndBox.CornerMin();
+  gp_Pnt aBndBoxMax = aBndBox.CornerMax();
+  return Select3D_BndBox3d (SelectMgr_Vec3 (aBndBoxMin.X(), aBndBoxMin.Y(), aBndBoxMin.Z()),
+                            SelectMgr_Vec3 (aBndBoxMax.X(), aBndBoxMax.Y(), aBndBoxMax.Z()));
 }
 
 //=======================================================================
@@ -189,3 +258,29 @@ void SelectMgr_SensitiveEntitySet::removeOwner (const Handle(SelectMgr_EntityOwn
     }
   }
 }
+
+//=======================================================================
+// function : UpdateBVH
+// purpose  :
+//=======================================================================
+void SelectMgr_SensitiveEntitySet::UpdateBVH (const Handle(Graphic3d_Camera)& theCamera,
+                                              const Graphic3d_Mat4d& theProjectionMat,
+                                              const Graphic3d_Mat4d& theWorldViewMat,
+                                              const Graphic3d_WorldViewProjState& theViewState,
+                                              const Standard_Integer theViewportWidth,
+                                              const Standard_Integer theViewportHeight)
+{
+  if (!myHasEntityWithPersistence)
+  {
+    return;
+  }
+  myAdaptorPersistent = new SelectMgr_AdaptorPersistent(theCamera, theProjectionMat,
+                                                        theWorldViewMat,
+                                                        theViewState,
+                                                        theViewportWidth,
+                                                        theViewportHeight);
+
+  MarkDirty();
+  BVH();
+  myAdaptorPersistent.Nullify();
+}
index 61f8d84f921959dd942ab00a3d4d58af27ae319d..7a8b3e593e5225e20cd8a4e8e6ec6120417907ad 100644 (file)
@@ -25,6 +25,8 @@
 #include <SelectMgr_SensitiveEntity.hxx>
 #include <SelectMgr_Selection.hxx>
 
+class SelectMgr_AdaptorPersistent;
+
 typedef NCollection_IndexedMap<Handle(SelectMgr_SensitiveEntity)> SelectMgr_IndexedMapOfHSensitive;
 typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwners;
 
@@ -79,6 +81,18 @@ public:
   //! Returns map of owners.
   const SelectMgr_MapOfOwners& Owners() const { return myOwnersMap; }
 
+  //! Returns map of entities.
+  Standard_EXPORT Standard_Boolean HasEntityWithPersistence() const { return myHasEntityWithPersistence; }
+
+  //! Updates outdated BVH trees and remembers the last state of the
+  //! camera view-projection matrices and viewport (window) dimensions.
+  Standard_EXPORT void UpdateBVH (const Handle(Graphic3d_Camera)& theCamera,
+                                  const Graphic3d_Mat4d& theProjectionMat,
+                                  const Graphic3d_Mat4d& theWorldViewMat,
+                                  const Graphic3d_WorldViewProjState& theViewState,
+                                  const Standard_Integer theViewportWidth,
+                                  const Standard_Integer theViewportHeight);
+  
 protected:
 
   //! Adds entity owner to the map of owners (or increases its counter if it is already there).
@@ -91,6 +105,8 @@ private:
 
   SelectMgr_IndexedMapOfHSensitive mySensitives;     //!< Map of entities and its corresponding index in BVH
   SelectMgr_MapOfOwners myOwnersMap;                 //!< Map of entity owners and its corresponding number of sensitives
+  Handle(SelectMgr_AdaptorPersistent) myAdaptorPersistent; //!< camera parameters to apply transform persistence
+  Standard_Boolean myHasEntityWithPersistence;       //!< flag if some of sensitive entity has own transform persistence
 };
 
 #endif // _SelectMgr_SensitiveEntitySet_HeaderFile
index 30805b3e38375a5a359c2f6208b9946340cfbae2..4449f36e5cf5d28d1f90ec43f0eba3b09267e449 100644 (file)
@@ -369,6 +369,17 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
     return;
   }
 
+  if (anEntitySet->HasEntityWithPersistence())
+  {
+    Standard_Integer aWidth;
+    Standard_Integer aHeight;
+    mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
+    anEntitySet->UpdateBVH (mySelectingVolumeMgr.Camera(),
+                            mySelectingVolumeMgr.ProjectionMatrix(),
+                            mySelectingVolumeMgr.WorldViewMatrix(),
+                            mySelectingVolumeMgr.WorldViewProjState(),
+                            aWidth, aHeight);
+  }
   const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
   gp_GTrsf aInversedTrsf;
   if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
@@ -400,7 +411,8 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
   SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
                                         ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
                                         : theMgr;
-  if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
+  if (!anEntitySet->HasEntityWithPersistence()
+   && !aMgr.Overlaps (aSensitivesTree->MinPoint (0),
                       aSensitivesTree->MaxPoint (0)))
   {
     return;
@@ -551,9 +563,33 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
           const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
           if (aSensitive->IsActiveForSelection())
           {
+            gp_GTrsf aInversedTrsf_;
+            if (aSensitive->BaseSensitive()->TransformPersistence().IsNull())
+            {
+              aInversedTrsf_ = aInversedTrsf;
+            }
+            else
+            {
+              gp_GTrsf aTPers;
+              Graphic3d_Mat4d aMat = aSensitive->BaseSensitive()->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
+
+              aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
+              aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
+              aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
+              aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
+              aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
+              aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
+              aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
+              aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
+              aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
+              aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
+
+              aInversedTrsf_ = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
+            }
+
             const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
-            computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
-            checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
+            computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf_, aScaledTrnsfFrustums, aTmpMgr);
+            checkOverlap (anEnt, aInversedTrsf_, aTmpMgr);
           }
         }
       }