]> OCCT Git - occt.git/commitdiff
Fix selection for flipped objects
authormzernova <mzernova@opencascade.com>
Fri, 16 Aug 2024 11:46:59 +0000 (12:46 +0100)
committermzernova <mzernova@opencascade.com>
Mon, 3 Mar 2025 12:11:31 +0000 (12:11 +0000)
16 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_CStructure.cxx
src/Graphic3d/Graphic3d_CStructure.hxx
src/Graphic3d/Graphic3d_Flipper.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_Flipper.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_Group.hxx
src/Graphic3d/Graphic3d_Structure.cxx
src/OpenGl/OpenGl_Group.cxx
src/Select3D/Select3D_SensitiveEntity.cxx
src/Select3D/Select3D_SensitiveEntity.hxx
src/SelectMgr/SelectMgr.cxx
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 ec1f20b4df2905a952d6b81f232ed5c624cf28f0..1011a60076c6b711a0eb181a78a7527f0d10b6c2 100755 (executable)
@@ -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
index bc9b09ca08981b0592303e8d6f5a6ca44db8dc14..fbf0eccd9fb721890cc7ec7d82709340b1b9f666 100644 (file)
@@ -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),
index 8138cd165f3afc27c48b76d762decece23dc2f5d..ad3356a416a012ecdafb6b80930c4c14aa1abeba 100644 (file)
@@ -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 (file)
index 0000000..3978fc8
--- /dev/null
@@ -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 (file)
index 0000000..ee4ee7e
--- /dev/null
@@ -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
index eb9aca4f98dfae347c834076378412a17de359c2..9a0c6672673e6f0bb0dcde5cb1253a3e878cab31 100644 (file)
@@ -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
index eace8db06f574d6c7ae66bdecbbdf241de7ba148..02918356082d720f5ea25a48dbca8f6862b6d837 100644 (file)
@@ -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);
index 4592c63fbc2e8dc9b4a6336ddb8d822fa5b1fd71..d7defc215558d648f203b47eee22d5951216022e 100644 (file)
@@ -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);
+  }
 }
 
 // =======================================================================
index d63246c9e31fc7a069fc408e6730e7b08a2d671f..3ed5ac568317a64e6976df523b60eb9eb08f119e 100644 (file)
@@ -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());
 
index 5c119e26d80423c050b43fb61380c5b9d734c04e..2ea1e3ac2a94337a2a72bb6ff4ccf28d47fcaa65 100644 (file)
@@ -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)
index 1f647b3d282ba1b4d59cb5005b57bc59bc073e0f..c0a9f0363113798d7a03fe7bbdfd7ef5457d5693 100644 (file)
@@ -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);
index 49794719082f6aee9fad6882c4111ab1fce1f0dd..292f27d1bce2680470e8f8d24363dec0445f25f5 100644 (file)
@@ -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())
         {
index fa1a7367016ced881eee4130d033b648353319d5..95bcc9833ea12e6c999de46d6de3fb5a350b7657 100644 (file)
@@ -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;
         }
index 5f853514b75cce5fa27ef3ff25f3bc000e90f213..6b0b0a8a4602625d75f36fa21929eb604c1c4ea4 100644 (file)
@@ -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());
index 01752fd2f3a9793ad7b9c115dfa82479bc488260..0b29bbd4585790bcc42fac3511bff9aab0011b54 100644 (file)
@@ -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
index 6c23ee7ee973a27e32ae8fded0d440a1c851b168..cbf95f4a131c99d2284def18b3a36dfa976aafe2 100644 (file)
@@ -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)