diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES
index ec1f20b4df..1011a60076 100755
--- a/src/Graphic3d/FILES
+++ b/src/Graphic3d/FILES
@@ -65,6 +65,8 @@ Graphic3d_DataStructureManager.cxx
 Graphic3d_DataStructureManager.hxx
 Graphic3d_DiagnosticInfo.hxx
 Graphic3d_DisplayPriority.hxx
+Graphic3d_Flipper.cxx
+Graphic3d_Flipper.hxx
 Graphic3d_FrameStats.cxx
 Graphic3d_FrameStats.hxx
 Graphic3d_FrameStatsCounter.hxx
diff --git a/src/Graphic3d/Graphic3d_CStructure.cxx b/src/Graphic3d/Graphic3d_CStructure.cxx
index bc9b09ca08..fbf0eccd9f 100644
--- a/src/Graphic3d/Graphic3d_CStructure.cxx
+++ b/src/Graphic3d/Graphic3d_CStructure.cxx
@@ -25,14 +25,15 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CStructure,Standard_Transient)
 //purpose  :
 //=============================================================================
 Graphic3d_CStructure::Graphic3d_CStructure (const Handle(Graphic3d_StructureManager)& theManager)
-: myGraphicDriver  (theManager->GraphicDriver()),
-  myId             (-1),
-  myZLayer         (Graphic3d_ZLayerId_Default),
+: myGraphicDriver   (theManager->GraphicDriver()),
+  myId              (-1),
+  myZLayer          (Graphic3d_ZLayerId_Default),
   myPriority        (Graphic3d_DisplayPriority_Normal),
   myPreviousPriority(Graphic3d_DisplayPriority_Normal),
-  myIsCulled       (Standard_True),
-  myBndBoxClipCheck(Standard_True),
-  myHasGroupTrsf   (Standard_False),
+  myIsCulled        (Standard_True),
+  myBndBoxClipCheck (Standard_True),
+  myHasGroupTrsf    (Standard_False),
+  myHasGroupFlipping(Standard_False),
   //
   IsInfinite       (0),
   stick            (0),
diff --git a/src/Graphic3d/Graphic3d_CStructure.hxx b/src/Graphic3d/Graphic3d_CStructure.hxx
index 8138cd165f..ad3356a416 100644
--- a/src/Graphic3d/Graphic3d_CStructure.hxx
+++ b/src/Graphic3d/Graphic3d_CStructure.hxx
@@ -94,6 +94,12 @@ public:
   //! Set if some groups might have transform persistence.
   void SetGroupTransformPersistence (bool theValue) { myHasGroupTrsf = theValue; }
 
+  //! Return TRUE if some groups might have flipping options; FALSE by default.
+  bool HasGroupFlipping() const { return myHasGroupFlipping; }
+
+  //! Set if some groups might have flipping options.
+  void SetGroupFlipping (bool theValue) { myHasGroupFlipping = theValue; }
+
   //! @return associated clip planes
   const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const
   {
@@ -243,6 +249,7 @@ protected:
   Standard_Boolean myBndBoxClipCheck;  //!< Flag responsible for checking of bounding box clipping before drawing of object
 
   Standard_Boolean myHasGroupTrsf;     //!< flag specifying that some groups might have transform persistence
+  Standard_Boolean myHasGroupFlipping; //!< flag specifying that some groups might have flipping options
 
 public:
 
diff --git a/src/Graphic3d/Graphic3d_Flipper.cxx b/src/Graphic3d/Graphic3d_Flipper.cxx
new file mode 100644
index 0000000000..3978fc8ac8
--- /dev/null
+++ b/src/Graphic3d/Graphic3d_Flipper.cxx
@@ -0,0 +1,26 @@
+// Copyright (c) 2024 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_Flipper.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Flipper, Standard_Transient)
+
+// =======================================================================
+// function : DumpJson
+// purpose  :
+// =======================================================================
+void Graphic3d_Flipper::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
+{
+  OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myRefPlane)
+}
diff --git a/src/Graphic3d/Graphic3d_Flipper.hxx b/src/Graphic3d/Graphic3d_Flipper.hxx
new file mode 100644
index 0000000000..ee4ee7eec4
--- /dev/null
+++ b/src/Graphic3d/Graphic3d_Flipper.hxx
@@ -0,0 +1,224 @@
+// Copyright (c) 2024 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_Flipper_HeaderFile
+#define _Graphic3d_Flipper_HeaderFile
+
+#include <gp_Ax2.hxx>
+#include <BVH_Box.hxx>
+#include <NCollection_Mat4.hxx>
+
+DEFINE_STANDARD_HANDLE(Graphic3d_Flipper, Standard_Transient)
+
+//! Flipper definition.
+class Graphic3d_Flipper : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_Flipper, Standard_Transient)
+
+public:
+
+  //! Constructor.
+  Graphic3d_Flipper (const gp_Ax2& theRefPlane)
+  : myRefPlane (theRefPlane)
+  { }
+
+public:
+
+  //! Return reference plane for flipping.
+  gp_Ax2 RefPlane() const { return myRefPlane; }
+
+  //! Set reference plane for flipping.
+  void SetRefPlane (const gp_Ax2& theValue) { myRefPlane = theValue; }
+
+public:
+
+
+  //! Apply transformation to bounding box of presentation.
+  //! @param theWorldView [in] the world view transformation matrix.
+  //! @param theBoundingBox [in/out] the bounding box to transform.
+  template<class T>
+  void Apply (const NCollection_Mat4<T>& theWorldView,
+              Bnd_Box& theBoundingBox) const;
+
+  //! Apply transformation to bounding box of presentation
+  //! @param theWorldView [in] the world view transformation matrix.
+  //! @param theBoundingBox [in/out] the bounding box to transform.
+  template<class T>
+  void Apply (const NCollection_Mat4<T>& theWorldView,
+              BVH_Box<T, 3>& theBoundingBox) const;
+
+  //! Compute transformation.
+  //! Computed matrix can be applied to model world transformation
+  //! of an object to implement effect of transformation persistence.
+  //! @param theWorldView [in] the world view transformation matrix.
+  template<class T>
+  NCollection_Mat4<T> Compute (const NCollection_Mat4<T>& theWorldView) const;
+
+  //! Dumps the content of me into the stream
+  Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
+
+private:
+
+  gp_Ax2  myRefPlane;
+};
+
+// =======================================================================
+// function : Apply
+// purpose  : Apply transformation to bounding box of presentation.
+// =======================================================================
+template<class T>
+void Graphic3d_Flipper::Apply (const NCollection_Mat4<T>& theWorldView,
+                               Bnd_Box& theBoundingBox) const
+{
+  if (theBoundingBox.IsVoid())
+  {
+    return;
+  }
+
+  T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+
+  theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+
+  typename BVH_Box<T, 3>::BVH_VecNt aMin (aXmin, aYmin, aZmin);
+  typename BVH_Box<T, 3>::BVH_VecNt aMax (aXmax, aYmax, aZmax);
+  BVH_Box<T, 3> aBBox (aMin, aMax);
+
+  Apply (theWorldView, aBBox);
+
+  theBoundingBox = Bnd_Box();
+  theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
+                         aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z());
+}
+
+// =======================================================================
+// function : Apply
+// purpose  : Apply transformation to bounding box of presentation.
+// =======================================================================
+template<class T>
+void Graphic3d_Flipper::Apply (const NCollection_Mat4<T>& theWorldView,
+                               BVH_Box<T, 3>& theBoundingBox) const
+{
+  NCollection_Mat4<T> aTPers = Compute (theWorldView);
+  if (aTPers.IsIdentity()
+  || !theBoundingBox.IsValid())
+  {
+    return;
+  }
+
+  const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
+  const typename BVH_Box<T, 3>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
+
+  typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
+  anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
+  anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
+  anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
+  anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
+  anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
+
+  theBoundingBox.Clear();
+  for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
+  {
+    typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
+    aCorner  = aTPers * aCorner;
+    aCorner = aCorner / aCorner.w();
+    theBoundingBox.Add (typename BVH_Box<T, 3>::BVH_VecNt (aCorner.x(), aCorner.y(), aCorner.z()));
+  }
+}
+
+// =======================================================================
+// function : Compute
+// purpose  : Compute transformation.
+// =======================================================================
+template<class T>
+NCollection_Mat4<T> Graphic3d_Flipper::Compute (const NCollection_Mat4<T>& theWorldView) const
+{
+  NCollection_Vec4<T> aReferenceOrigin (myRefPlane.Location().X(),
+                                        myRefPlane.Location().Y(),
+                                        myRefPlane.Location().Z(),
+                                        1.0f);
+  NCollection_Vec4<T> aReferenceX (myRefPlane.XDirection().X(),
+                                   myRefPlane.XDirection().Y(),
+                                   myRefPlane.XDirection().Z(),
+                                   1.0f);
+  NCollection_Vec4<T> aReferenceY (myRefPlane.YDirection().X(),
+                                   myRefPlane.YDirection().Y(),
+                                   myRefPlane.YDirection().Z(),
+                                    1.0f);
+  NCollection_Vec4<T> aReferenceZ (myRefPlane.Axis().Direction().X(),
+                                   myRefPlane.Axis().Direction().Y(),
+                                   myRefPlane.Axis().Direction().Z(),
+                                   1.0f);
+
+  NCollection_Mat4<T> aMatrixMV;
+  aMatrixMV.Convert (theWorldView);
+
+  const NCollection_Vec4<T> aMVReferenceOrigin = aMatrixMV * aReferenceOrigin;
+  const NCollection_Vec4<T> aMVReferenceX = aMatrixMV * NCollection_Vec4<T>(aReferenceX.xyz() + aReferenceOrigin.xyz(), 1.0f);
+  const NCollection_Vec4<T> aMVReferenceY = aMatrixMV * NCollection_Vec4<T>(aReferenceY.xyz() + aReferenceOrigin.xyz(), 1.0f);
+  const NCollection_Vec4<T> aMVReferenceZ = aMatrixMV * NCollection_Vec4<T>(aReferenceZ.xyz() + aReferenceOrigin.xyz(), 1.0f);
+
+  const NCollection_Vec4<T> aDirX = aMVReferenceX - aMVReferenceOrigin;
+  const NCollection_Vec4<T> aDirY = aMVReferenceY - aMVReferenceOrigin;
+  const NCollection_Vec4<T> aDirZ = aMVReferenceZ - aMVReferenceOrigin;
+
+  Standard_Boolean isReversedX = aDirX.xyz().Dot (NCollection_Vec3<T>::DX()) < 0.0f;
+  Standard_Boolean isReversedY = aDirY.xyz().Dot (NCollection_Vec3<T>::DY()) < 0.0f;
+  Standard_Boolean isReversedZ = aDirZ.xyz().Dot (NCollection_Vec3<T>::DZ()) < 0.0f;
+
+  // compute flipping (rotational transform)
+  NCollection_Mat4<T> aTransform;
+  if ((isReversedX || isReversedY) && !isReversedZ)
+  {
+    // invert by Z axis: left, up vectors mirrored
+    aTransform.SetColumn (0, -aTransform.GetColumn(0).xyz());
+    aTransform.SetColumn (1, -aTransform.GetColumn(1).xyz());
+  }
+  else if (isReversedY && isReversedZ)
+  {
+    // rotate by X axis: up, forward vectors mirrored
+    aTransform.SetColumn (1, -aTransform.GetColumn(1).xyz());
+    aTransform.SetColumn (2, -aTransform.GetColumn(2).xyz());
+  }
+  else if (isReversedZ)
+  {
+    // rotate by Y axis: left, forward vectors mirrored
+    aTransform.SetColumn (0, -aTransform.GetColumn(0).xyz());
+    aTransform.SetColumn (2, -aTransform.GetColumn(2).xyz());
+  }
+  else
+  {
+    return NCollection_Mat4<T>();
+  }
+
+  // do rotation in origin around reference system "forward" direction
+  NCollection_Mat4<T> aTranslation;
+  NCollection_Mat4<T> aTranslationInv;
+  aTranslation.SetColumn (3, aMVReferenceOrigin.xyz());
+  aTranslation.Inverted (aTranslationInv);
+
+  NCollection_Mat4<T> aRefAxes;
+  NCollection_Mat4<T> aRefInv;
+  aRefAxes.SetColumn (0, aReferenceX.xyz());
+  aRefAxes.SetColumn (1, aReferenceY.xyz());
+  aRefAxes.SetColumn (2, aReferenceZ.xyz());
+  aRefAxes.SetColumn (3, aReferenceOrigin.xyz());
+  aRefAxes.Inverted (aRefInv);
+
+  aTransform = aRefAxes * aTransform * aRefInv;
+  return aTransform;
+}
+
+#endif // _Graphic3d_Flipper_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_Group.hxx b/src/Graphic3d/Graphic3d_Group.hxx
index eb9aca4f98..9a0c667267 100644
--- a/src/Graphic3d/Graphic3d_Group.hxx
+++ b/src/Graphic3d/Graphic3d_Group.hxx
@@ -21,6 +21,7 @@
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_MapOfAspectsToAspects.hxx>
 #include <Standard_CString.hxx>
+#include <Graphic3d_Flipper.hxx>
 #include <Graphic3d_Vertex.hxx>
 #include <Graphic3d_TextPath.hxx>
 #include <Graphic3d_HorizontalTextAlignment.hxx>
@@ -128,6 +129,9 @@ public:
   //! sets the stencil test to theIsEnabled state;
   Standard_EXPORT virtual void SetStencilTestOptions (const Standard_Boolean theIsEnabled) = 0;
 
+  //! Return flipper.
+  const Handle(Graphic3d_Flipper)& Flipper() const { return myFlipper; }
+
   //! sets the flipping to theIsEnabled state.
   Standard_EXPORT virtual void SetFlippingOptions (const Standard_Boolean theIsEnabled, const gp_Ax2& theRefPlane) = 0;
 
@@ -292,6 +296,7 @@ protected:
 protected:
 
   Handle(Graphic3d_TransformPers) myTrsfPers; //!< current transform persistence
+  Handle(Graphic3d_Flipper)       myFlipper;  //!< current transform persistence
   Graphic3d_Structure* myStructure;     //!< pointer to the parent structure
   Graphic3d_BndBox4f   myBounds;        //!< bounding box
   bool                 myIsClosed;      //!< flag indicating closed volume
diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx
index eace8db06f..0291835608 100644
--- a/src/Graphic3d/Graphic3d_Structure.cxx
+++ b/src/Graphic3d/Graphic3d_Structure.cxx
@@ -81,6 +81,7 @@ void Graphic3d_Structure::clear (const Standard_Boolean theWithDestruction)
   GraphicClear (theWithDestruction);
 
   myCStructure->SetGroupTransformPersistence (false);
+  myCStructure->SetGroupFlipping (false);
   myStructureManager->Clear (this, theWithDestruction);
 
   Update (true);
diff --git a/src/OpenGl/OpenGl_Group.cxx b/src/OpenGl/OpenGl_Group.cxx
index 4592c63fbc..d7defc2155 100644
--- a/src/OpenGl/OpenGl_Group.cxx
+++ b/src/OpenGl/OpenGl_Group.cxx
@@ -215,6 +215,11 @@ void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled,
   OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
   aFlipper->SetOptions (theIsEnabled);
   AddElement (aFlipper);
+  if (theIsEnabled)
+  {
+    myStructure->CStructure()->SetGroupFlipping (true);
+    myFlipper = new Graphic3d_Flipper (theRefPlane);
+  }
 }
 
 // =======================================================================
diff --git a/src/Select3D/Select3D_SensitiveEntity.cxx b/src/Select3D/Select3D_SensitiveEntity.cxx
index d63246c9e3..3ed5ac5683 100644
--- a/src/Select3D/Select3D_SensitiveEntity.cxx
+++ b/src/Select3D/Select3D_SensitiveEntity.cxx
@@ -31,6 +31,23 @@ Select3D_SensitiveEntity::Select3D_SensitiveEntity (const Handle(SelectMgr_Entit
   //
 }
 
+// =======================================================================
+// function : SetFlippingOptions
+// purpose  :
+// =======================================================================
+void Select3D_SensitiveEntity::SetFlippingOptions (const Standard_Boolean theIsEnabled,
+                                                   const gp_Ax2&          theRefPlane)
+{
+  if (theIsEnabled)
+  {
+    myFlipper = new Graphic3d_Flipper(theRefPlane);
+  }
+  else
+  {
+    myFlipper = nullptr;
+  }
+}
+
 //=======================================================================
 //function : DumpJson
 //purpose  :
@@ -40,8 +57,9 @@ void Select3D_SensitiveEntity::DumpJson (Standard_OStream& theOStream, Standard_
   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
 
   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myOwnerId.get())
-  OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, myTrsfPers.get())
-  OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, mySFactor)
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myTrsfPers.get())
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myFlipper.get())
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mySFactor)
 
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, NbSubElements());
 
diff --git a/src/Select3D/Select3D_SensitiveEntity.hxx b/src/Select3D/Select3D_SensitiveEntity.hxx
index 5c119e26d8..2ea1e3ac2a 100644
--- a/src/Select3D/Select3D_SensitiveEntity.hxx
+++ b/src/Select3D/Select3D_SensitiveEntity.hxx
@@ -21,6 +21,7 @@
 #include <Select3D_BndBox3d.hxx>
 #include <SelectMgr_SelectingVolumeManager.hxx>
 #include <TopLoc_Location.hxx>
+#include <Graphic3d_Flipper.hxx>
 
 class Graphic3d_TransformPers;
 class SelectMgr_EntityOwner;
@@ -95,6 +96,13 @@ public:
   //! Set transformation persistence.
   virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
 
+  //! Return coordinate system for flipping.
+  const Handle(Graphic3d_Flipper)& Flipper() const { return myFlipper; }
+
+  //! Set transformation persistence.
+  Standard_EXPORT virtual void SetFlippingOptions (const Standard_Boolean theIsEnabled,
+                                                   const gp_Ax2&          theRefPlane);
+
   //! Dumps the content of me into the stream
   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
@@ -104,10 +112,10 @@ protected:
 
 protected:
 
-  Handle(SelectMgr_EntityOwner) myOwnerId;
+  Handle(SelectMgr_EntityOwner)   myOwnerId;
   Handle(Graphic3d_TransformPers) myTrsfPers;
-  Standard_Integer mySFactor;
-
+  Handle(Graphic3d_Flipper)       myFlipper;
+  Standard_Integer                mySFactor;
 };
 
 DEFINE_STANDARD_HANDLE(Select3D_SensitiveEntity, Standard_Transient)
diff --git a/src/SelectMgr/SelectMgr.cxx b/src/SelectMgr/SelectMgr.cxx
index 1f647b3d28..c0a9f03631 100644
--- a/src/SelectMgr/SelectMgr.cxx
+++ b/src/SelectMgr/SelectMgr.cxx
@@ -203,6 +203,10 @@ void SelectMgr::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& thePrs,
   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
   {
     const Handle(Select3D_SensitiveEntity)& anEnt = aSelEntIter.Value()->BaseSensitive();
+    if (!anEnt->Flipper().IsNull())
+    {
+      thePrs->CurrentGroup()->SetFlippingOptions (Standard_True, anEnt->Flipper()->RefPlane());
+    }
     if (Handle(Select3D_SensitiveBox) aSensBox = Handle(Select3D_SensitiveBox)::DownCast (anEnt))
     {
       addBoundingBox (aSeqLines, aSensBox, theLoc);
diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
index 4979471908..292f27d1bc 100644
--- a/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
+++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
@@ -124,6 +124,35 @@ namespace
 
         Bnd_Box aBoundingBox;
         anObject->BoundingBox (aBoundingBox);
+
+        // processing presentations with own flipping
+        for (PrsMgr_Presentations::Iterator aPrsIter(anObject->Presentations()); aPrsIter.More(); aPrsIter.Next())
+        {
+          const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.Value();
+          if (!aPrs3d->CStructure()->HasGroupTransformPersistence() && !aPrs3d->CStructure()->HasGroupFlipping())
+          {
+            continue;
+          }
+
+          for (Graphic3d_SequenceOfGroup::Iterator aGroupIter(aPrs3d->Groups()); aGroupIter.More(); aGroupIter.Next())
+          {
+            const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
+            const Graphic3d_BndBox4f& aBndBox = aGroup->BoundingBox();
+            if (aGroup->Flipper().IsNull()
+             || !aBndBox.IsValid())
+            {
+              continue;
+            }
+
+            Bnd_Box aGroupBox;
+            aGroupBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
+                              aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
+            aGroup->Flipper()->Apply (theWorldViewMat, aGroupBox);
+
+            aBoundingBox.Add (aGroupBox);
+          }
+        }
+
         if (!aBoundingBox.IsVoid()
          && !anObject->TransformPersistence().IsNull())
         {
diff --git a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx
index fa1a736701..95bcc9833e 100644
--- a/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx
+++ b/src/SelectMgr/SelectMgr_SelectableObjectSet.hxx
@@ -200,7 +200,8 @@ private:
       for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next())
       {
         const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue();
-        if (aPrs3d->CStructure()->HasGroupTransformPersistence())
+        if (aPrs3d->CStructure()->HasGroupTransformPersistence()
+         || aPrs3d->CStructure()->HasGroupFlipping())
         {
           return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent;
         }
diff --git a/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx b/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx
index 5f853514b7..6b0b0a8a46 100644
--- a/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx
+++ b/src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx
@@ -29,6 +29,7 @@ SelectMgr_SensitiveEntitySet::SelectMgr_SensitiveEntitySet (const Handle(Select3
 : BVH_PrimitiveSet3d (theBuilder)
 {
   myNbEntityWithPersistence = 0;
+  myNbEntityWithFlipping = 0;
 }
 
 //=======================================================================
@@ -51,6 +52,10 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_SensitiveEntit
   {
     ++myNbEntityWithPersistence;
   }
+  if (!theEntity->BaseSensitive()->Flipper().IsNull())
+  {
+    ++myNbEntityWithFlipping;
+  }
   MarkDirty();
 }
 
@@ -79,6 +84,10 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_Selection)& th
     {
       ++myNbEntityWithPersistence;
     }
+    if (!aSensEnt->BaseSensitive()->Flipper().IsNull())
+    {
+      ++myNbEntityWithFlipping;
+    }
   }
   MarkDirty();
 }
@@ -107,6 +116,10 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
     {
       --myNbEntityWithPersistence;
     }
+    if (!aSensEnt->BaseSensitive()->Flipper().IsNull())
+    {
+      --myNbEntityWithFlipping;
+    }
 
     mySensitives.RemoveLast();
     removeOwner (aSensEnt->BaseSensitive()->OwnerId());
diff --git a/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx b/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx
index 01752fd2f3..0b29bbd458 100644
--- a/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx
+++ b/src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx
@@ -79,6 +79,9 @@ public:
   //! Returns map of entities.
   Standard_Boolean HasEntityWithPersistence() const { return myNbEntityWithPersistence > 0; }
 
+  //! Returns true if exists entities with flipping parameters.
+  Standard_Boolean HasEntityWithFlipping() const { return myNbEntityWithFlipping > 0; }
+
 protected:
 
   //! Adds entity owner to the map of owners (or increases its counter if it is already there).
@@ -92,6 +95,7 @@ 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
   Standard_Integer                 myNbEntityWithPersistence; //!< number of sensitive entities that have own transform persistence
+  Standard_Integer                 myNbEntityWithFlipping;    //!< number of sensitive entities that have own flipping options
 };
 
 #endif // _SelectMgr_SensitiveEntitySet_HeaderFile
diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx
index 6c23ee7ee9..cbf95f4a13 100644
--- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx
+++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx
@@ -384,6 +384,8 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
 
   const bool hasEntityTrsfPers = anEntitySet->HasEntityWithPersistence()
                              && !theCamera.IsNull();
+  const bool hasEntityFlipped = anEntitySet->HasEntityWithFlipping();
+
   const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
   gp_GTrsf aInversedTrsf;
   if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
@@ -412,6 +414,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
                                         ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
                                         : theMgr;
   if (!hasEntityTrsfPers
+   && !hasEntityFlipped
    && !aMgr.OverlapsBox (aSensitivesTree->MinPoint (0),
                          aSensitivesTree->MaxPoint (0)))
   {
@@ -495,9 +498,11 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
       const Standard_Integer aLeftChildIdx  = aSensitivesTree->Child<0> (aNode);
       const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
       const Standard_Boolean isLeftChildIn  = hasEntityTrsfPers
+                                           || hasEntityFlipped
                                            || aMgr.OverlapsBox (aSensitivesTree->MinPoint (aLeftChildIdx),
                                                                 aSensitivesTree->MaxPoint (aLeftChildIdx));
       const Standard_Boolean isRightChildIn = hasEntityTrsfPers
+                                           || hasEntityFlipped
                                            || aMgr.OverlapsBox (aSensitivesTree->MinPoint (aRightChildIdx),
                                                                 aSensitivesTree->MaxPoint (aRightChildIdx));
       if (isLeftChildIn
@@ -585,8 +590,16 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
             aInvSensTrsf = (aTPers * gp_GTrsf(theObject->Transformation())).Inverted();
           }
 
-          computeFrustum (anEnt, theMgr, aMgr, aInvSensTrsf, aScaledTrnsfFrustums, aTmpMgr);
-          checkOverlap (anEnt, aInvSensTrsf, aTmpMgr);
+          gp_GTrsf aFlippingTrsf;
+          if (!anEnt->Flipper().IsNull())
+          {
+            const Graphic3d_Mat4d aMat = anEnt->Flipper()->Compute (theWorldViewMat);
+            aFlippingTrsf.SetMat4 (aMat);
+          }
+
+          gp_GTrsf aInvFlippingAndPers = aFlippingTrsf * aInvSensTrsf;
+          computeFrustum (anEnt, theMgr, aMgr, aInvFlippingAndPers, aScaledTrnsfFrustums, aTmpMgr);
+          checkOverlap (anEnt, aInvFlippingAndPers, aTmpMgr);
         }
       }
       if (aHead < 0)