From 3f33ea7e5ab573191d86afbfba5fc0435e7ef15f Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 14 Oct 2020 10:05:46 +0300 Subject: [PATCH] 0027919: Visualization - support multiple transformation persistence groups within single presentation - 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 | 4 + src/Select3D/Select3D_SensitiveEntity.hxx | 8 ++ .../SelectMgr_SelectableObjectSet.cxx | 36 ++++++- .../SelectMgr_SelectableObjectSet.hxx | 12 +++ .../SelectMgr_SensitiveEntitySet.cxx | 97 ++++++++++++++++++- .../SelectMgr_SensitiveEntitySet.hxx | 16 +++ src/SelectMgr/SelectMgr_ViewerSelector.cxx | 42 +++++++- 7 files changed, 207 insertions(+), 8 deletions(-) diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index a3f1e4e4d4..16a56f4024 100644 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -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; diff --git a/src/Select3D/Select3D_SensitiveEntity.hxx b/src/Select3D/Select3D_SensitiveEntity.hxx index 3015a14d5b..9abc398b47 100644 --- a/src/Select3D/Select3D_SensitiveEntity.hxx +++ b/src/Select3D/Select3D_SensitiveEntity.hxx @@ -27,6 +27,7 @@ #include #include +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; }; diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx index 15be832ffd..a8bbbae118 100644 --- a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx +++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx @@ -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()), diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx index 2925e42b42..51dea02574 100644 --- a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx +++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx @@ -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) diff --git a/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx b/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx index bad281a5e1..e9c42a42e2 100644 --- a/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx +++ b/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx @@ -15,11 +15,45 @@ #include +#include #include #include 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(); +} diff --git a/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx b/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx index 61f8d84f92..7a8b3e593e 100644 --- a/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx +++ b/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx @@ -25,6 +25,8 @@ #include #include +class SelectMgr_AdaptorPersistent; + typedef NCollection_IndexedMap SelectMgr_IndexedMapOfHSensitive; typedef NCollection_DataMap 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 diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index 30805b3e38..4449f36e5c 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -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 >& 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); } } } -- 2.39.5