1
0
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:
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

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

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