mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0024070: OpenGL capped object-level clipping planes
Graphical clipping: - Use "Graphic3d_ClipPlane" to defined clipping for PrsMgr_PresentableObject (local clipping), for V3d_View (global clipping). Get rid of old implementations: - Remove Visual3d_ClipPlane. - Port V3d_Plane to Graphic3d_ClipPlane core. Selection Sensitives: - Port "Matches" method to add full set of arguments (SelectBasics_PickArgs), including min-max depth coming from selector. - Get rid of transient data for pair Matches -> ComputeDepth. - Extend SelectMgr_ViewerSelector::LoadResult to work with local clipping, add virtual callbacks to compute globa/local depth clipping for picking. Capping rendering algorithm: - Recursive rendering algorithm for OpenGl_Groups. - Introduced Rendering filter for groups. Clipping plane management in TKOpenGl: - Added OpenGl_ClippingState to OpenGl_Context. DRAWEXE commands: - Ported "vclipplane" command for new approach. - Added "vsettexturemode" command for changing texture details in views (enable / disable textures). Correct DownCast syntax (compilation error) Fix new compiler warnings tests/bugs/vis/bug22906 migrated to the new vclipplane syntax
This commit is contained in:
@@ -30,12 +30,15 @@ class ViewerSelector3d from StdSelect inherits ViewerSelector from SelectMgr
|
||||
uses
|
||||
View from V3d,
|
||||
Selection from SelectMgr,
|
||||
EntityOwner from SelectMgr,
|
||||
Projector from Select3D,
|
||||
Group from Graphic3d,
|
||||
Structure from Graphic3d,
|
||||
SetOfHClipPlane from Graphic3d,
|
||||
Array1OfReal from TColStd,
|
||||
Array1OfPnt2d from TColgp,
|
||||
SensitivityMode from StdSelect
|
||||
SensitivityMode from StdSelect,
|
||||
Lin from gp
|
||||
|
||||
is
|
||||
|
||||
@@ -106,10 +109,6 @@ is
|
||||
---Category: Internal Methods
|
||||
-- -----------------
|
||||
|
||||
ReactivateProjector(me:mutable);
|
||||
---Level: Internal
|
||||
---Purpose: Puts back the address of the current projector in sensitive primitives...
|
||||
|
||||
UpdateProj(me :mutable;
|
||||
aView: View from V3d) returns Boolean is static private;
|
||||
---Level: Internal
|
||||
@@ -153,9 +152,46 @@ is
|
||||
is static private;
|
||||
---Level: Internal
|
||||
|
||||
|
||||
SetClipping (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is protected;
|
||||
---Level: Internal
|
||||
---Purpose: Set view clipping for the selector.
|
||||
-- @param thePlanes [in] the view planes.
|
||||
|
||||
ComputeClipRange (me; thePlanes : SetOfHClipPlane from Graphic3d;
|
||||
thePickLine : Lin from gp;
|
||||
theDepthMin, theDepthMax : out Real from Standard)
|
||||
is protected;
|
||||
---Level: Internal
|
||||
---Purpose: Computed depth boundaries for the passed set of clipping planes and picking line.
|
||||
-- @param thePlanes [in] the planes.
|
||||
-- @param thePickLine [in] the picking line.
|
||||
-- @param theDepthMin [out] minimum depth limit.
|
||||
-- @param theDepthMax [out] maximum depth limit.
|
||||
|
||||
PickingLine (me; theX, theY : Real from Standard)
|
||||
returns Lin from gp
|
||||
is redefined protected;
|
||||
---Level: Internal
|
||||
---Purpose: For more details please refer to base class.
|
||||
|
||||
DepthClipping (me; theX, theY : Real from Standard;
|
||||
theMin, theMax : out Real from Standard)
|
||||
is redefined protected;
|
||||
---Level: Internal
|
||||
---Purpose: For more details please refer to base class.
|
||||
|
||||
DepthClipping (me; theX, theY : Real from Standard;
|
||||
theOwner : EntityOwner from SelectMgr;
|
||||
theMin, theMax : out Real from Standard)
|
||||
is redefined protected;
|
||||
---Level: Internal
|
||||
---Purpose: For more details please refer to base class.
|
||||
|
||||
HasDepthClipping (me; theOwner : EntityOwner from SelectMgr)
|
||||
returns Boolean is redefined protected;
|
||||
---Level: Internal
|
||||
---Purpose: For more details please refer to base class.
|
||||
|
||||
fields
|
||||
|
||||
myprj : Projector from Select3D;
|
||||
@@ -174,8 +210,8 @@ fields
|
||||
myareagroup : Group from Graphic3d;
|
||||
mysensgroup : Group from Graphic3d;
|
||||
mystruct: Structure from Graphic3d;
|
||||
myClipPlanes : SetOfHClipPlane from Graphic3d;
|
||||
|
||||
|
||||
end ViewerSelector3d;
|
||||
|
||||
|
||||
|
@@ -29,10 +29,12 @@
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <V3d_PerspectiveView.hxx>
|
||||
#include <V3d_Plane.hxx>
|
||||
#include <Select3D_SensitiveEntity.hxx>
|
||||
#include <Graphic3d_ArrayOfPolylines.hxx>
|
||||
#include <Graphic3d_SetOfHClipPlane.hxx>
|
||||
#include <SelectMgr_SelectableObject.hxx>
|
||||
#include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
|
||||
#include <SelectBasics_ListOfBox2d.hxx>
|
||||
#include <Visual3d_TransientManager.hxx>
|
||||
@@ -197,57 +199,13 @@ void StdSelect_ViewerSelector3d
|
||||
const Standard_Integer YPix,
|
||||
const Handle(V3d_View)& aView)
|
||||
{
|
||||
SetClipping (aView->GetClipPlanes());
|
||||
UpdateProj(aView);
|
||||
Standard_Real Xr3d,Yr3d,Zr3d;
|
||||
gp_Pnt2d P2d;
|
||||
aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
|
||||
myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
|
||||
|
||||
// compute depth limits if clipping plane(s) enabled
|
||||
gp_Lin anEyeLine = myprj->Shoot (P2d.X(), P2d.Y());
|
||||
Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
|
||||
Standard_Real aDepthFrom = ShortRealFirst();
|
||||
Standard_Real aDepthTo = ShortRealLast();
|
||||
for (aView->InitActivePlanes(); aView->MoreActivePlanes(); aView->NextActivePlanes())
|
||||
{
|
||||
aView->ActivePlane()->Plane (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
|
||||
const gp_Dir& anEyeLineDir = anEyeLine.Direction();
|
||||
gp_Dir aPlaneNormal (aPlaneA, aPlaneB, aPlaneC);
|
||||
|
||||
Standard_Real aDotProduct = anEyeLineDir.Dot (aPlaneNormal);
|
||||
Standard_Real aDirection = -(aPlaneD + anEyeLine.Location().XYZ().Dot (aPlaneNormal.XYZ()));
|
||||
if (Abs (aDotProduct) < Precision::Angular())
|
||||
{
|
||||
// eyeline parallel to the clipping plane
|
||||
if (aDirection > 0.0)
|
||||
{
|
||||
// invalidate the interval
|
||||
aDepthTo = ShortRealFirst();
|
||||
aDepthFrom = ShortRealFirst();
|
||||
break;
|
||||
}
|
||||
// just ignore this plane
|
||||
continue;
|
||||
}
|
||||
|
||||
// compute distance along the eyeline from eyeline location to intersection with clipping plane
|
||||
Standard_Real aDepth = aDirection / aDotProduct;
|
||||
|
||||
// reduce depth limits
|
||||
if (aDotProduct < 0.0)
|
||||
{
|
||||
if (aDepth < aDepthTo)
|
||||
{
|
||||
aDepthTo = aDepth;
|
||||
}
|
||||
}
|
||||
else if (aDepth > aDepthFrom)
|
||||
{
|
||||
aDepthFrom = aDepth;
|
||||
}
|
||||
}
|
||||
myprj->DepthMinMax (aDepthFrom, aDepthTo);
|
||||
|
||||
InitSelect(P2d.X(),P2d.Y());
|
||||
}
|
||||
|
||||
@@ -1087,18 +1045,123 @@ void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selecti
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReactivateProjector
|
||||
//function : SetClipping
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void StdSelect_ViewerSelector3d::ReactivateProjector()
|
||||
void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SetOfHClipPlane& thePlanes)
|
||||
{
|
||||
Handle(SelectBasics_SensitiveEntity) BS;
|
||||
for (SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive it (myentities); it.More(); it.Next())
|
||||
myClipPlanes = thePlanes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeClipRange
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SetOfHClipPlane& thePlanes,
|
||||
const gp_Lin& thePickLine,
|
||||
Standard_Real& theDepthMin,
|
||||
Standard_Real& theDepthMax) const
|
||||
{
|
||||
theDepthMin = RealFirst();
|
||||
theDepthMax = RealLast();
|
||||
Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
|
||||
|
||||
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
|
||||
for (; aPlaneIt.More(); aPlaneIt.Next())
|
||||
{
|
||||
BS = it.Value();
|
||||
if (BS->Is3D())
|
||||
const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
|
||||
if (!aClipPlane->IsOn())
|
||||
continue;
|
||||
|
||||
gp_Pln aGeomPlane = aClipPlane->ToPlane();
|
||||
|
||||
aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
|
||||
|
||||
const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
|
||||
const gp_Dir& aPickDir = thePickLine.Direction();
|
||||
const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
|
||||
const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
|
||||
|
||||
Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
|
||||
Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
|
||||
|
||||
// check whether the pick line is parallel to clip plane
|
||||
if (Abs (aDotProduct) < Precision::Angular())
|
||||
{
|
||||
(*((Handle(Select3D_SensitiveEntity)*) &BS))->SetLastPrj (myprj);
|
||||
if (aDistance > 0.0)
|
||||
{
|
||||
// line lies above the plane, thus no selection is possible
|
||||
theDepthMin = 0.0;
|
||||
theDepthMax = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// line lies below the plane and is not clipped, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
// compute distance to point of pick line intersection with the plane
|
||||
Standard_Real aIntDist = aDistance / aDotProduct;
|
||||
|
||||
// change depth limits for case of opposite and directed planes
|
||||
if (aDotProduct < 0.0)
|
||||
{
|
||||
theDepthMax = Min (aIntDist, theDepthMax);
|
||||
}
|
||||
else if (aIntDist > theDepthMin)
|
||||
{
|
||||
theDepthMin = Max (aIntDist, theDepthMin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PickingLine
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
|
||||
{
|
||||
return myprj->Shoot (theX, theY);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DepthClipping
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
|
||||
const Standard_Real theY,
|
||||
Standard_Real& theDepthMin,
|
||||
Standard_Real& theDepthMax) const
|
||||
{
|
||||
return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DepthClipping
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
|
||||
const Standard_Real theY,
|
||||
const Handle(SelectMgr_EntityOwner)& theOwner,
|
||||
Standard_Real& theDepthMin,
|
||||
Standard_Real& theDepthMax) const
|
||||
{
|
||||
return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
|
||||
PickingLine (theX, theY),
|
||||
theDepthMin, theDepthMax);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HasDepthClipping
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
|
||||
{
|
||||
if (!theOwner->HasSelectable())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
|
||||
return (aSelectable->GetClipPlanes().Size() > 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user