Graphic3d_DataStructureManager.hxx
Graphic3d_DiagnosticInfo.hxx
Graphic3d_DisplayPriority.hxx
+Graphic3d_Flipper.cxx
+Graphic3d_Flipper.hxx
Graphic3d_FrameStats.cxx
Graphic3d_FrameStats.hxx
Graphic3d_FrameStatsCounter.hxx
//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),
//! 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
{
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:
--- /dev/null
+// 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)
+}
--- /dev/null
+// 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
#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>
//! 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;
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
GraphicClear (theWithDestruction);
myCStructure->SetGroupTransformPersistence (false);
+ myCStructure->SetGroupFlipping (false);
myStructureManager->Clear (this, theWithDestruction);
Update (true);
OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane);
aFlipper->SetOptions (theIsEnabled);
AddElement (aFlipper);
+ if (theIsEnabled)
+ {
+ myStructure->CStructure()->SetGroupFlipping (true);
+ myFlipper = new Graphic3d_Flipper (theRefPlane);
+ }
}
// =======================================================================
//
}
+// =======================================================================
+// 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 :
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());
#include <Select3D_BndBox3d.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <TopLoc_Location.hxx>
+#include <Graphic3d_Flipper.hxx>
class Graphic3d_TransformPers;
class SelectMgr_EntityOwner;
//! 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;
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)
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);
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())
{
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;
}
: BVH_PrimitiveSet3d (theBuilder)
{
myNbEntityWithPersistence = 0;
+ myNbEntityWithFlipping = 0;
}
//=======================================================================
{
++myNbEntityWithPersistence;
}
+ if (!theEntity->BaseSensitive()->Flipper().IsNull())
+ {
+ ++myNbEntityWithFlipping;
+ }
MarkDirty();
}
{
++myNbEntityWithPersistence;
}
+ if (!aSensEnt->BaseSensitive()->Flipper().IsNull())
+ {
+ ++myNbEntityWithFlipping;
+ }
}
MarkDirty();
}
{
--myNbEntityWithPersistence;
}
+ if (!aSensEnt->BaseSensitive()->Flipper().IsNull())
+ {
+ --myNbEntityWithFlipping;
+ }
mySensitives.RemoveLast();
removeOwner (aSensEnt->BaseSensitive()->OwnerId());
//! 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).
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
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())
? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
: theMgr;
if (!hasEntityTrsfPers
+ && !hasEntityFlipped
&& !aMgr.OverlapsBox (aSensitivesTree->MinPoint (0),
aSensitivesTree->MaxPoint (0)))
{
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
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)