- misprint in distance calculation in SelectMgr_RectangularFrustum::IsClipped is corrected;
- selecting volume manager in clipping check in SelectMgr_ViewerSelector::checkOverlap was replaced ;
- added view-defined clipping planes check to SelectMgr_RectangularFrustum;
- test case for issue #26973.
SelectMgr_TypeOfBVHUpdate.hxx
SelectMgr_TypeOfUpdate.hxx
SelectMgr_VectorTypes.hxx
+SelectMgr_ViewClipRange.hxx
SelectMgr_ViewerSelector.cxx
SelectMgr_ViewerSelector.hxx
SelectMgr_ViewerSelector.lxx
return DBL_MAX;
}
+//=======================================================================
+// function : DetectedPoint
+// purpose :
+//=======================================================================
gp_Pnt SelectMgr_BaseFrustum::DetectedPoint (const Standard_Real /*theDepth*/) const
{
return gp_Pnt (RealLast(), RealLast(), RealLast());
Standard_EXPORT virtual Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
const Standard_Real theDepth);
+ //! Valid for point selection only!
+ //! Computes depth range for global (defined for the whole view) clipping planes.
+ Standard_EXPORT virtual void SetViewClipping (const Graphic3d_SequenceOfHClipPlane& /*thePlanes*/) {};
+
DEFINE_STANDARD_RTTIEXT(SelectMgr_BaseFrustum,Standard_Transient)
protected:
// {i, j, k} vectors and store them to corresponding class fields
cacheVertexProjections (this);
+ myViewClipRange.Clear();
+
myScale = 1.0;
}
// {i, j, k} vectors and store them to corresponding class fields
cacheVertexProjections (this);
+ myViewClipRange.Clear();
+
myScale = 1.0;
}
cacheVertexProjections (aRes);
+ aRes->myViewClipRange = myViewClipRange;
+
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
}
theDepth = aNearestPnt.Distance (myNearPickedPnt);
- return Standard_True;
+ return isViewClippingOk (theDepth);
}
// =======================================================================
theDepth = aDetectedPnt.Distance (myNearPickedPnt) * myScale;
- return Standard_True;
+ return isViewClippingOk (theDepth);
}
// =======================================================================
return Standard_False;
segmentSegmentDistance (thePnt1, thePnt2, theDepth);
- return Standard_True;
+
+ return isViewClippingOk (theDepth);
}
// =======================================================================
theDepth);
}
- return Standard_True;
+ return isViewClippingOk (theDepth);
}
// =======================================================================
// is detected correctly, and distance to triangle's plane can be measured as distance to its arbitrary vertex.
const gp_XYZ aDiff = myNearPickedPnt.XYZ() - thePnt1.XYZ();
theDepth = aTriangleNormal.Dot (aDiff) * myScale;
- return Standard_True;
+
+ return isViewClippingOk (theDepth);
}
gp_XYZ anEdge = (thePnt1.XYZ() - myNearPickedPnt.XYZ()) * (1.0 / anAlpha);
{
gp_Pnt aDetectedPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTime;
theDepth = myNearPickedPnt.Distance (aDetectedPnt) * myScale;
- return Standard_True;
+
+ return isViewClippingOk (theDepth);
}
gp_Pnt aPnts[3] = {thePnt1, thePnt2, thePnt3};
segmentSegmentDistance (aPnts[aNearestEdgeIdx], aPnts[(aNearestEdgeIdx + 1) % 3], theDepth);
}
- return Standard_True;
+ return isViewClippingOk (theDepth);
}
// =======================================================================
}
// =======================================================================
-// function : IsClipped
-// purpose : Checks if the point of sensitive in which selection was
-// detected belongs to the region defined by clipping planes
+// function : computeClippingRange
+// purpose :
// =======================================================================
-Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
- const Standard_Real theDepth)
+void SelectMgr_RectangularFrustum::computeClippingRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
+ Standard_Real& theDepthMin,
+ Standard_Real& theDepthMax)
{
- Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
- Standard_Real aMaxDepth = DBL_MAX;
- Standard_Real aMinDepth = -DBL_MAX;
+ theDepthMax = DBL_MAX;
+ theDepthMin = -DBL_MAX;
Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
- for ( ; aPlaneIt.More(); aPlaneIt.Next())
+ for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
if (!aClipPlane->IsOn())
const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ();
- Standard_Real aDotProduct = myViewRayDir.XYZ().Dot (aPlaneDirXYZ);
- Standard_Real aDistance = - myNearPickedPnt.XYZ().Dot (aPlaneDirXYZ) +
- aPlaneD;
+ Standard_Real aDotProduct = myViewRayDir.XYZ ().Dot (aPlaneDirXYZ);
+ Standard_Real aDistance = - myNearPickedPnt.XYZ ().Dot (aPlaneDirXYZ)
+ - aPlaneD;
// check whether the pick line is parallel to clip plane
if (Abs (aDotProduct) < Precision::Angular())
// change depth limits for case of opposite and directed planes
if (aDotProduct < 0.0)
{
- aMaxDepth = Min (aDistToPln, aMaxDepth);
+ theDepthMax = Min (aDistToPln, theDepthMax);
}
- else if (aDistToPln > aMinDepth)
+ else if (aDistToPln > theDepthMin)
{
- aMinDepth = Max (aDistToPln, aMinDepth);
+ theDepthMin = Max (aDistToPln, theDepthMin);
}
}
+}
+
+// =======================================================================
+// function : IsClipped
+// purpose : Checks if the point of sensitive in which selection was
+// detected belongs to the region defined by clipping planes
+// =======================================================================
+Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
+ const Standard_Real theDepth)
+{
+ Standard_Real aMaxDepth, aMinDepth;
+ computeClippingRange (thePlanes, aMinDepth, aMaxDepth);
return (theDepth <= aMinDepth || theDepth >= aMaxDepth);
}
+
+// =======================================================================
+// function : SetViewClipping
+// purpose :
+// =======================================================================
+void SelectMgr_RectangularFrustum::SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
+{
+ if (thePlanes.Size() == 0)
+ {
+ myViewClipRange.Clear();
+ return;
+ }
+
+ Standard_Real aMaxDepth, aMinDepth;
+ computeClippingRange (thePlanes, aMinDepth, aMaxDepth);
+ myViewClipRange.Set (aMinDepth, aMaxDepth);
+}
+
+// =======================================================================
+// function : isViewClippingOk
+// purpose :
+// =======================================================================
+Standard_Boolean SelectMgr_RectangularFrustum::isViewClippingOk (const Standard_Real theDepth) const
+{
+ if (!myViewClipRange.IsValid())
+ return Standard_True;
+
+ return myViewClipRange.MaxDepth() > theDepth
+ && myViewClipRange.MinDepth() < theDepth;
+}
#define _SelectMgr_RectangularFrustum_HeaderFile
#include <SelectMgr_Frustum.hxx>
+#include <SelectMgr_ViewClipRange.hxx>
//! This class contains representation of rectangular selecting frustum, created in case
//! of point and box selection, and algorithms for overlap detection between selecting
Standard_EXPORT virtual Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
const Standard_Real theDepth) Standard_OVERRIDE;
+ //! Valid for point selection only!
+ //! Computes depth range for global (defined for the whole view) clipping planes.
+ Standard_EXPORT virtual void SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes) Standard_OVERRIDE;
+
//! A set of helper functions that return rectangular selecting frustum data
inline const gp_Pnt* GetVertices() const { return myVertices; }
const gp_Pnt& thePntOnPlane,
Standard_Real& theDepth);
+ //! Computes valid depth range for the given clipping planes
+ Standard_EXPORT void computeClippingRange (const Graphic3d_SequenceOfHClipPlane& thePlanes,
+ Standard_Real& theDepthMin,
+ Standard_Real& theDepthMax);
+
+ //! Returns false if theDepth must be clipped by current view clip range
+ Standard_EXPORT Standard_Boolean isViewClippingOk (const Standard_Real theDepth) const;
+
private:
void cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum);
private:
- gp_Pnt myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane
- gp_Pnt myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
- gp_Vec myViewRayDir;
- gp_Pnt2d myMousePos; //!< Mouse coordinates
- Standard_Real myScale; //!< Scale factor of applied transformation, if there was any
+ gp_Pnt myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane
+ gp_Pnt myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
+ gp_Vec myViewRayDir;
+ gp_Pnt2d myMousePos; //!< Mouse coordinates
+ Standard_Real myScale; //!< Scale factor of applied transformation, if there was any
+ SelectMgr_ViewClipRange myViewClipRange;
};
#endif // _SelectMgr_RectangularFrustum_HeaderFile
Standard_Boolean SelectMgr_SelectingVolumeManager::IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
const Standard_Real& theDepth)
{
- if (myActiveSelectionType == Point)
+ if (myActiveSelectionType != Point)
return Standard_False;
return mySelectingVolumes[Frustum]->IsClipped (thePlanes, theDepth);
reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
return aFr->GetFarPnt();
}
+
+//=======================================================================
+// function : SetViewClipping
+// purpose :
+//=======================================================================
+void SelectMgr_SelectingVolumeManager::SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
+{
+ if (myActiveSelectionType != Point)
+ return;
+
+ mySelectingVolumes[Frustum]->SetViewClipping (thePlanes);
+}
Standard_EXPORT virtual Standard_Boolean IsOverlapAllowed() const Standard_OVERRIDE;
+ //! Valid for point selection only!
+ //! Computes depth range for global (defined for the whole view) clipping planes.
+ Standard_EXPORT void SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes);
+
//! A set of helper functions that return rectangular selecting frustum data
Standard_EXPORT const gp_Pnt* GetVertices() const;
--- /dev/null
+// Created on: 2015-12-15
+// Created by: Varvara POSKONINA
+// Copyright (c) 2005-2014 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 _SelectMgr_ViewClipRange_HeaderFile
+#define _SelectMgr_ViewClipRange_HeaderFile
+
+#include <Standard_TypeDef.hxx>
+
+//! Class for handling depth clipping range.
+//! It is used to perform checks in case if global (for the whole view)
+//! clipping planes are defined inside of SelectMgr_RectangularFrustum
+//! class methods.
+class SelectMgr_ViewClipRange
+{
+public:
+ //! Creates new empty view clip range
+ SelectMgr_ViewClipRange()
+ {
+ Clear();
+ }
+
+ //! Sets boundaries and validates view clipping range
+ void Set (const Standard_Real theDepthMin, const Standard_Real theDepthMax)
+ {
+ myMin = theDepthMin;
+ myMax = theDepthMax;
+ myIsValid = Standard_True;
+ }
+
+ //! Returns true if clip range is set and depth of each matched
+ //! primitive must be tested for satisfying the defined interval
+ Standard_Boolean IsValid() const
+ {
+ return myIsValid;
+ }
+
+ //! Returns the upper bound of valid depth range
+ Standard_Real MaxDepth() const
+ {
+ return myMax;
+ }
+
+ //! Returns the lower bound of valid depth range
+ Standard_Real MinDepth() const
+ {
+ return myMin;
+ }
+
+ //! Invalidates view clipping range
+ void Clear()
+ {
+ myIsValid = Standard_False;
+ }
+
+private:
+ Standard_Real myMin; //!< Lower bound of valid depth range
+ Standard_Real myMax; //!< Upper bound of valid depth range
+ Standard_Boolean myIsValid; //!< The flag is set to true when range boundaries are set and depth check must be performed
+};
+
+#endif // _SelectMgr_ViewClipRange_HeaderFile
{
if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
{
- Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
- aPickResult.Depth());
+ Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
+ aPickResult.Depth());
if (isClipped)
return;
}
const Standard_Integer theYPix,
const Handle(V3d_View)& theView)
{
- SetClipping (theView->GetClipPlanes());
-
if(myToUpdateTolerance)
{
mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
static_cast<Standard_Real> (theYPix));
mySelectingVolumeMgr.BuildSelectingVolume (aMousePos);
+ mySelectingVolumeMgr.SetViewClipping (theView->GetClipPlanes());
TraverseSensitives();
}
}
}
-//=======================================================================
-//function : SetClipping
-//purpose :
-//=======================================================================
-void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes)
-{
- myClipPlanes = thePlanes;
-}
-
//=======================================================================
//function : HasDepthClipping
//purpose :
DEFINE_STANDARD_RTTIEXT(StdSelect_ViewerSelector3d,SelectMgr_ViewerSelector)
-protected:
-
- //! Set view clipping for the selector.
- //! @param thePlanes [in] the view planes.
- Standard_EXPORT void SetClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes);
-
private:
void ComputeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
const Graphic3d_TransformPers& theTransPers);
Graphic3d_SequenceOfStructure myStructs;
- Graphic3d_SequenceOfHClipPlane myClipPlanes;
};
DEFINE_STANDARD_HANDLE(StdSelect_ViewerSelector3d, SelectMgr_ViewerSelector)
--- /dev/null
+puts "============"
+puts "CR26973"
+puts "============"
+puts ""
+
+##########################################################################################
+puts "Visualization - selection of entities hidden by clipping planes is broken"
+##########################################################################################
+
+pload MODELING VISUALIZATION
+
+vinit View1
+vclear
+vaxo
+vsetdispmode 1
+
+proc OCC26973 { toTestViewPlanes toApplyTrsf theImgIdr theCaseName} {
+ if {$toApplyTrsf == "1"} {
+ box b -100 -100 -100 1 1 1
+ ttranslate b 100 100 100
+ } else {
+ box b 1 1 1
+ }
+
+ vdisplay b
+ vfit
+ vselmode b 4 1
+
+ vclipplane create pln
+ if {$toTestViewPlanes == "1"} {
+ vclipplane set pln view Driver1/Viewer1/View1
+ } else {
+ vclipplane set pln object b
+ }
+ vclipplane change pln equation 0 1 0 -0.5
+
+ vselect 200 140
+ set aTestInfo "Test case: "
+ append aTestInfo "clipping planes applied to "
+ set aDumpFileName $theImgIdr/${theCaseName}
+ if {$toTestViewPlanes == "1"} {
+ append aTestInfo "view, "
+ append aDumpFileName "_view"
+ } else {
+ append aTestInfo "object, "
+ append aDumpFileName "_obj"
+ }
+ append aTestInfo "object trsf is "
+ if {$toApplyTrsf == "1"} {
+ append aTestInfo "on"
+ append aDumpFileName "_with_trsf.png"
+ } else {
+ append aTestInfo "off"
+ append aDumpFileName "_wo_trsf.png"
+ }
+
+ if {[vnbselected] != 1} {
+ puts "ERROR: can not select face."
+ puts $aTestInfo
+ }
+ set aSelectedFace [string trim [lindex [split [vstate] "\n"] 1] ]
+ if {$aSelectedFace != "Face #1"} {
+ puts "ERROR: wrong face is selected."
+ puts "Actually seleced face: $aSelectedFace"
+ puts $aTestInfo
+ }
+
+ vdump $aDumpFileName
+ vremove -all
+ vclipplane delete pln
+}
+
+# check global clipping planes selection
+OCC26973 1 0 $imagedir $casename
+OCC26973 1 1 $imagedir $casename
+
+# check object clipping planes selection
+OCC26973 0 0 $imagedir $casename
+OCC26973 0 1 $imagedir $casename