]> OCCT Git - occt-copy.git/commitdiff
0027919: Visualization - support multiple transformation persistence groups within... CR0_DMUReviewer_IR-2020-05-15_CR23854
authornds <nds@opencascade.com>
Wed, 14 Oct 2020 07:05:46 +0000 (10:05 +0300)
committernds <nds@opencascade.com>
Fri, 22 Jan 2021 15:06:53 +0000 (18:06 +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)

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);
           }
         }
       }