From 02b4631b15d051db0280e00204f2ded538213ff5 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) --- 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 b579ee3a22..1fd0fa3396 100644 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -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; diff --git a/src/Select3D/Select3D_SensitiveEntity.hxx b/src/Select3D/Select3D_SensitiveEntity.hxx index 19b039eafd..137c52559d 100644 --- a/src/Select3D/Select3D_SensitiveEntity.hxx +++ b/src/Select3D/Select3D_SensitiveEntity.hxx @@ -28,6 +28,7 @@ #include #include +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; }; 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 4a650d03f8..4b81acb2d3 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(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(); +} 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 79c5f1cc61..81f77dc383 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -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 >& 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); } } } -- 2.39.5