]> OCCT Git - occt-copy.git/commitdiff
0027919: Visualization - support multiple transformation persistence groups within... CR0_DMUReviewer_IR-2020-05-15_CR23854_1
authornds <nds@opencascade.com>
Wed, 14 Oct 2020 07:05:46 +0000 (10:05 +0300)
committernds <nds@opencascade.com>
Sun, 7 Mar 2021 05:11:52 +0000 (08:11 +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)

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 b579ee3a22967ed3873769d1cb435a75baa68276..1fd0fa3396eeec21b1d0978832725ab39d37e753 100644 (file)
@@ -800,6 +800,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 19b039eafd908b22b7198fd94de69acd8e33999f..137c52559db0abf59b5519b6c912ae00e24078f1 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.
@@ -91,6 +92,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;
 
@@ -101,6 +108,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 4a650d03f8e29afcf6a5aac66349081e089c2fd2..4b81acb2d3a5c5b8fe79b429007db11c4c4bb0d4 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(Select3D_SensitiveEntity, 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();
 }
@@ -71,6 +110,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();
 }
@@ -98,6 +142,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();
@@ -109,7 +154,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()));
 }
 
 //=======================================================================
@@ -191,3 +260,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 79c5f1cc616704bb4c844ffaf3b1157a1b953a5f..81f77dc383e48344865e8b57465cbd0e72115fda 100644 (file)
@@ -347,6 +347,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())
@@ -378,7 +389,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;
@@ -529,9 +541,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);
           }
         }
       }