mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0024521: Visualization - automatic back face culling is not turned on for Solids packed into compound
StdPrs_ToolShadedShape::IsClosed(): - return true if shape is closed Solid (NOT just free closed Shell) - accept compound of closed Solids as well - ignore Solids with incomplete triangulation TKOpenGl, automatically disable back face culling when: - clipping/capping planes are in effect - for translucent objects Update bug23227 test case (now back faces are clipped). OpenGl_Workspace::AspectFace() - disable culling in case of hatched style
This commit is contained in:
parent
fd03ee4b3b
commit
3b1817a9e2
@ -46,7 +46,8 @@ typedef TEL_COLOUR* tel_colour;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TelCullNone,
|
||||
TelCullUndefined = -1,
|
||||
TelCullNone = 0,
|
||||
TelCullFront,
|
||||
TelCullBack
|
||||
} TelCullMode;
|
||||
|
@ -27,9 +27,9 @@ namespace
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_Clipping::OpenGl_Clipping ()
|
||||
: myPlanes(),
|
||||
myPlaneStates(),
|
||||
myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5))
|
||||
: myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5)),
|
||||
myNbClipping (0),
|
||||
myNbCapping (0)
|
||||
{}
|
||||
|
||||
// =======================================================================
|
||||
@ -40,6 +40,8 @@ void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes)
|
||||
{
|
||||
myPlanes.Clear();
|
||||
myPlaneStates.Clear();
|
||||
myNbClipping = 0;
|
||||
myNbCapping = 0;
|
||||
Standard_Integer aLowerId = GL_CLIP_PLANE0;
|
||||
Standard_Integer aUpperId = GL_CLIP_PLANE0 + theMaxPlanes - 1;
|
||||
myEmptyPlaneIds = new Aspect_GenId (aLowerId, aUpperId);
|
||||
@ -104,6 +106,15 @@ void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes, const Equa
|
||||
|
||||
glEnable ((GLenum)anID);
|
||||
glClipPlane ((GLenum)anID, aPlane->GetEquation());
|
||||
if (aPlane->IsCapping())
|
||||
{
|
||||
++myNbCapping;
|
||||
}
|
||||
else
|
||||
{
|
||||
++myNbClipping;
|
||||
}
|
||||
|
||||
aPlaneIt.Next();
|
||||
}
|
||||
|
||||
@ -129,10 +140,22 @@ void OpenGl_Clipping::Remove (const Graphic3d_SequenceOfHClipPlane& thePlanes)
|
||||
}
|
||||
|
||||
Standard_Integer anID = myPlaneStates.Find (aPlane).ContextID;
|
||||
PlaneProps& aProps = myPlaneStates.ChangeFind (aPlane);
|
||||
if (aProps.IsEnabled)
|
||||
{
|
||||
glDisable ((GLenum)anID);
|
||||
if (aPlane->IsCapping())
|
||||
{
|
||||
--myNbCapping;
|
||||
}
|
||||
else
|
||||
{
|
||||
--myNbClipping;
|
||||
}
|
||||
}
|
||||
|
||||
myEmptyPlaneIds->Free (anID);
|
||||
myPlaneStates.UnBind (aPlane);
|
||||
|
||||
glDisable ((GLenum)anID);
|
||||
}
|
||||
|
||||
// renew collection of planes
|
||||
@ -173,10 +196,26 @@ void OpenGl_Clipping::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
|
||||
if (theIsEnabled)
|
||||
{
|
||||
glEnable (anID);
|
||||
if (thePlane->IsCapping())
|
||||
{
|
||||
++myNbCapping;
|
||||
}
|
||||
else
|
||||
{
|
||||
++myNbClipping;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable (anID);
|
||||
if (thePlane->IsCapping())
|
||||
{
|
||||
--myNbCapping;
|
||||
}
|
||||
else
|
||||
{
|
||||
--myNbClipping;
|
||||
}
|
||||
}
|
||||
|
||||
aProps.IsEnabled = theIsEnabled;
|
||||
|
@ -81,6 +81,24 @@ public: //! @name non-modifying getters
|
||||
return myPlaneStates.Find (thePlane).IsEnabled;
|
||||
}
|
||||
|
||||
//! @return true if there are enabled clipping planes (NOT capping)
|
||||
inline Standard_Boolean IsClippingOn() const
|
||||
{
|
||||
return myNbClipping > 0;
|
||||
}
|
||||
|
||||
//! @return true if there are enabled capping planes
|
||||
inline Standard_Boolean IsCappingOn() const
|
||||
{
|
||||
return myNbCapping > 0;
|
||||
}
|
||||
|
||||
//! @return true if there are enabled clipping or capping planes
|
||||
inline Standard_Boolean IsClippingOrCappingOn() const
|
||||
{
|
||||
return (myNbClipping + myNbCapping) > 0;
|
||||
}
|
||||
|
||||
public: //! @name clipping state modification commands
|
||||
|
||||
//! Add planes to the context clipping at the specified system of coordinates.
|
||||
@ -198,9 +216,11 @@ private:
|
||||
typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), PlaneProps> OpenGl_MapOfPlaneStates;
|
||||
typedef NCollection_Handle<Aspect_GenId> OpenGl_EmptyPlaneIds;
|
||||
|
||||
Graphic3d_SequenceOfHClipPlane myPlanes; //!< defined clipping planes.
|
||||
OpenGl_MapOfPlaneStates myPlaneStates; //!< map of clip planes bound for the props.
|
||||
OpenGl_EmptyPlaneIds myEmptyPlaneIds; //!< generator of empty ids.
|
||||
Graphic3d_SequenceOfHClipPlane myPlanes; //!< defined clipping planes
|
||||
OpenGl_MapOfPlaneStates myPlaneStates; //!< map of clip planes bound for the props
|
||||
OpenGl_EmptyPlaneIds myEmptyPlaneIds; //!< generator of empty ids
|
||||
Standard_Boolean myNbClipping; //!< number of enabled clipping-only planes (NOT capping)
|
||||
Standard_Boolean myNbCapping; //!< number of enabled capping planes
|
||||
|
||||
private:
|
||||
|
||||
|
@ -166,6 +166,7 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
|
||||
TextParam_applied (NULL),
|
||||
ViewMatrix_applied (&myDefaultMatrix),
|
||||
StructureMatrix_applied (&myDefaultMatrix),
|
||||
myCullingMode (TelCullUndefined),
|
||||
myModelViewMatrix (myDefaultMatrix),
|
||||
PolygonOffset_applied (NULL)
|
||||
{
|
||||
@ -269,6 +270,7 @@ void OpenGl_Workspace::ResetAppliedAspect()
|
||||
TextParam_set = &myDefaultTextParam;
|
||||
TextParam_applied = NULL;
|
||||
PolygonOffset_applied = NULL;
|
||||
myCullingMode = TelCullUndefined;
|
||||
|
||||
AspectLine(Standard_True);
|
||||
AspectFace(Standard_True);
|
||||
|
@ -442,6 +442,7 @@ protected: //! @name fields related to status
|
||||
OpenGl_Material myMatFront; //!< current front material state (cached to reduce GL context updates)
|
||||
OpenGl_Material myMatBack; //!< current back material state
|
||||
OpenGl_Material myMatTmp; //!< temporary variable
|
||||
TelCullMode myCullingMode; //!< back face culling mode, applied from face aspect
|
||||
|
||||
//! Model matrix with applied structure transformations
|
||||
OpenGl_Matrix myModelViewMatrix;
|
||||
|
@ -319,7 +319,55 @@ const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean Wi
|
||||
|
||||
const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
|
||||
{
|
||||
if (!theToApply || (AspectFace_set == AspectFace_applied))
|
||||
if (!theToApply)
|
||||
{
|
||||
return AspectFace_set;
|
||||
}
|
||||
|
||||
if (!ActiveView()->Backfacing())
|
||||
{
|
||||
// manage back face culling mode, disable culling when clipping is enabled
|
||||
TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
|
||||
|| AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
|
||||
? TelCullNone
|
||||
: (TelCullMode )AspectFace_set->CullingMode();
|
||||
if (aCullingMode != TelCullNone
|
||||
&& myUseTransparency && !(NamedStatus & OPENGL_NS_2NDPASSDO))
|
||||
{
|
||||
// disable culling in case of translucent shading aspect
|
||||
if (AspectFace_set->IntFront().trans != 1.0f)
|
||||
{
|
||||
aCullingMode = TelCullNone;
|
||||
}
|
||||
}
|
||||
if (myCullingMode != aCullingMode)
|
||||
{
|
||||
myCullingMode = aCullingMode;
|
||||
switch (myCullingMode)
|
||||
{
|
||||
case TelCullNone:
|
||||
case TelCullUndefined:
|
||||
{
|
||||
glDisable (GL_CULL_FACE);
|
||||
break;
|
||||
}
|
||||
case TelCullFront:
|
||||
{
|
||||
glCullFace (GL_FRONT);
|
||||
glEnable (GL_CULL_FACE);
|
||||
break;
|
||||
}
|
||||
case TelCullBack:
|
||||
{
|
||||
glCullFace (GL_BACK);
|
||||
glEnable (GL_CULL_FACE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AspectFace_set == AspectFace_applied)
|
||||
{
|
||||
return AspectFace_set;
|
||||
}
|
||||
@ -365,34 +413,6 @@ const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean th
|
||||
}
|
||||
}
|
||||
|
||||
if (!ActiveView()->Backfacing())
|
||||
{
|
||||
const Tint aCullingMode = AspectFace_set->CullingMode();
|
||||
if (AspectFace_applied == NULL || AspectFace_applied->CullingMode() != aCullingMode)
|
||||
{
|
||||
switch ((TelCullMode )aCullingMode)
|
||||
{
|
||||
case TelCullNone:
|
||||
{
|
||||
glDisable (GL_CULL_FACE);
|
||||
break;
|
||||
}
|
||||
case TelCullFront:
|
||||
{
|
||||
glCullFace (GL_FRONT);
|
||||
glEnable (GL_CULL_FACE);
|
||||
break;
|
||||
}
|
||||
case TelCullBack:
|
||||
{
|
||||
glCullFace (GL_BACK);
|
||||
glEnable (GL_CULL_FACE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Aspect_POM_None means: do not change current settings
|
||||
if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ namespace
|
||||
Standard_Real aUmin (0.0), aUmax (0.0), aVmin (0.0), aVmax (0.0), dUmax (0.0), dVmax (0.0);
|
||||
|
||||
// precision for compare square distances
|
||||
const double aPreci = Precision::SquareConfusion();
|
||||
const Standard_Real aPreci = Precision::SquareConfusion();
|
||||
|
||||
if (!theDrawer->ShadingAspectGlobal())
|
||||
{
|
||||
@ -126,9 +126,12 @@ namespace
|
||||
nbVertices += T->NbNodes();
|
||||
}
|
||||
}
|
||||
|
||||
if (nbVertices > 2 && nbTriangles > 0)
|
||||
if (nbVertices < 3
|
||||
|| nbTriangles <= 0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Handle(Graphic3d_ArrayOfTriangles) aPArray
|
||||
= new Graphic3d_ArrayOfTriangles (nbVertices, 3 * nbTriangles,
|
||||
Standard_True, Standard_False, theHasTexels, Standard_True);
|
||||
@ -177,7 +180,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
// Fill parray with vertex and edge visibillity info
|
||||
// Fill array with vertex and edge visibility info
|
||||
const Poly_Array1OfTriangle& aTriangles = T->Triangles();
|
||||
for (Standard_Integer aTriIter = 1; aTriIter <= T->NbTriangles(); ++aTriIter)
|
||||
{
|
||||
@ -218,7 +221,7 @@ namespace
|
||||
}
|
||||
}
|
||||
Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPArray);
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,9 @@ uses
|
||||
Location from TopLoc
|
||||
is
|
||||
|
||||
IsClosed(myclass; aShape: Shape from TopoDS) returns Boolean from Standard;
|
||||
IsClosed (myclass; theShape : Shape from TopoDS) returns Boolean from Standard;
|
||||
---Purpose: Checks back faces visibility for specified shape (to activate back-face culling).
|
||||
-- @return true if shape is closed Solid or compound of closed Solids.
|
||||
|
||||
Triangulation(myclass; aFace: Face from TopoDS;
|
||||
loc : out Location from TopLoc)
|
||||
|
@ -32,13 +32,99 @@
|
||||
#include <TShort_HArray1OfShortReal.hxx>
|
||||
#include <TShort_Array1OfShortReal.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
//=======================================================================
|
||||
//function : isTriangulated
|
||||
//purpose : Returns true if all faces within shape are triangulated.
|
||||
// Same as BRepTools::Triangulation() but without extra checks.
|
||||
//=======================================================================
|
||||
static Standard_Boolean isTriangulated (const TopoDS_Shape& theShape)
|
||||
{
|
||||
TopLoc_Location aLocDummy;
|
||||
for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
|
||||
{
|
||||
const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
|
||||
const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation (aFace, aLocDummy);
|
||||
if (aTri.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsClosed
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean StdPrs_ToolShadedShape::IsClosed (const TopoDS_Shape& theShape)
|
||||
{
|
||||
return theShape.Closed();
|
||||
if (theShape.IsNull())
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
switch (theShape.ShapeType())
|
||||
{
|
||||
case TopAbs_COMPOUND:
|
||||
case TopAbs_COMPSOLID:
|
||||
default:
|
||||
{
|
||||
// check that compound consists of closed solids
|
||||
for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next())
|
||||
{
|
||||
const TopoDS_Shape& aShape = anIter.Value();
|
||||
if (!IsClosed (aShape))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
case TopAbs_SOLID:
|
||||
{
|
||||
for (TopoDS_Iterator anIter (theShape); anIter.More(); anIter.Next())
|
||||
{
|
||||
const TopoDS_Shape& aShape = anIter.Value();
|
||||
if (aShape.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aShape.ShapeType() == TopAbs_SHELL
|
||||
&& !aShape.Closed())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
else if (aShape.ShapeType() == TopAbs_FACE)
|
||||
{
|
||||
// invalid solid
|
||||
return Standard_False;
|
||||
}
|
||||
else if (!isTriangulated (aShape))
|
||||
{
|
||||
// mesh contains holes
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
case TopAbs_SHELL:
|
||||
case TopAbs_FACE:
|
||||
{
|
||||
// free faces / shell are not allowed
|
||||
return Standard_False;
|
||||
}
|
||||
case TopAbs_WIRE:
|
||||
case TopAbs_EDGE:
|
||||
case TopAbs_VERTEX:
|
||||
{
|
||||
// ignore
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@ -1,19 +1,19 @@
|
||||
puts "============"
|
||||
puts "OCC23227"
|
||||
puts "New Draw Harness command to estimate current geometry complexity of OpenGL scene"
|
||||
puts "============"
|
||||
puts ""
|
||||
#######################################################################
|
||||
# New Draw Harness command to estimate current geometry complexity of OpenGL scene
|
||||
#######################################################################
|
||||
|
||||
set BugNumber OCC23227
|
||||
|
||||
box b 1 2 3
|
||||
vinit
|
||||
vinit View1
|
||||
vclear
|
||||
vdisplay b
|
||||
vsetdispmode 1
|
||||
vfit
|
||||
set vfeedback1 [vfeedback]
|
||||
vdump $imagedir/${casename}_box.png
|
||||
|
||||
vclear
|
||||
set vfeedback2 [vfeedback]
|
||||
@ -29,7 +29,7 @@ if { ${llength_vfeedback1} < 36 || ${llength_vfeedback2} < 36 || ${IndexTriangle
|
||||
} else {
|
||||
set Triangles1 [lindex ${vfeedback1} ${IndexTriangles1}+1]
|
||||
set Triangles2 [lindex ${vfeedback2} ${IndexTriangles1}+1]
|
||||
if { ${Triangles1} == 12 && ${Triangles2} == 0 } {
|
||||
if { ${Triangles1} == 6 && ${Triangles2} == 0 } {
|
||||
puts "OK ${BugNumber}"
|
||||
} else {
|
||||
puts "Faulty ${BugNumber}"
|
||||
@ -37,4 +37,3 @@ if { ${llength_vfeedback1} < 36 || ${llength_vfeedback2} < 36 || ${IndexTriangle
|
||||
}
|
||||
|
||||
set only_screen 1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user