]> 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, 15 Jun 2021 07:35:54 +0000 (10:35 +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)

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 3aa4780fdb3630b27c926008207dc792a76bf2c8..b978733531da550dbc5d35e70e34a362bd3b78ec 100644 (file)
@@ -803,6 +803,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 f99df8fcdb5db9d08063d0df08d6e7ff39fb6d07..691376bbce5bc2d134993a6d9a1e447d756127eb 100644 (file)
@@ -28,6 +28,7 @@
 #include <SelectMgr_SelectingVolumeManager.hxx>
 #include <TopLoc_Location.hxx>
 
+class Graphic3d_TransformPers;
 class SelectMgr_EntityOwner;
 
 //! Abstract framework to define 3D sensitive entities.
@@ -94,6 +95,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;
 
@@ -104,6 +111,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 f29494f3fdeb5152394440974cf908ef40a33ee8..5dad45e969aba8884c21434af06cb11baed07e1a 100644 (file)
@@ -370,6 +370,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())
@@ -401,7 +412,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;
@@ -552,9 +564,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);
           }
         }
       }