1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +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:
apl
2013-09-19 16:58:00 +04:00
committed by bugmaster
parent 788cbaf4c4
commit 4269bd1b11
111 changed files with 4168 additions and 2293 deletions

View File

@@ -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);
}