};
typedef TEL_COLOUR* tel_colour;
-typedef enum
+typedef enum
{
- TelCullNone,
- TelCullFront,
+ TelCullUndefined = -1,
+ TelCullNone = 0,
+ TelCullFront,
TelCullBack
} TelCullMode;
// 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)
{}
// =======================================================================
{
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);
glEnable ((GLenum)anID);
glClipPlane ((GLenum)anID, aPlane->GetEquation());
+ if (aPlane->IsCapping())
+ {
+ ++myNbCapping;
+ }
+ else
+ {
+ ++myNbClipping;
+ }
+
aPlaneIt.Next();
}
}
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
if (theIsEnabled)
{
glEnable (anID);
+ if (thePlane->IsCapping())
+ {
+ ++myNbCapping;
+ }
+ else
+ {
+ ++myNbClipping;
+ }
}
else
{
glDisable (anID);
+ if (thePlane->IsCapping())
+ {
+ --myNbCapping;
+ }
+ else
+ {
+ --myNbClipping;
+ }
}
aProps.IsEnabled = theIsEnabled;
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.
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:
TextParam_applied (NULL),
ViewMatrix_applied (&myDefaultMatrix),
StructureMatrix_applied (&myDefaultMatrix),
+ myCullingMode (TelCullUndefined),
myModelViewMatrix (myDefaultMatrix),
PolygonOffset_applied (NULL)
{
TextParam_set = &myDefaultTextParam;
TextParam_applied = NULL;
PolygonOffset_applied = NULL;
+ myCullingMode = TelCullUndefined;
AspectLine(Standard_True);
AspectFace(Standard_True);
const OpenGl_Matrix* ViewMatrix_applied;
const OpenGl_Matrix* StructureMatrix_applied;
- 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
+ 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;
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;
}
}
}
- 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)
{
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())
{
nbVertices += T->NbNodes();
}
}
+ if (nbVertices < 3
+ || nbTriangles <= 0)
+ {
+ return Standard_False;
+ }
- if (nbVertices > 2 && nbTriangles > 0)
+ Handle(Graphic3d_ArrayOfTriangles) aPArray
+ = new Graphic3d_ArrayOfTriangles (nbVertices, 3 * nbTriangles,
+ Standard_True, Standard_False, theHasTexels, Standard_True);
+ for (SST.Init (theShape); SST.MoreFace(); SST.NextFace())
{
- Handle(Graphic3d_ArrayOfTriangles) aPArray
- = new Graphic3d_ArrayOfTriangles (nbVertices, 3 * nbTriangles,
- Standard_True, Standard_False, theHasTexels, Standard_True);
- for (SST.Init (theShape); SST.MoreFace(); SST.NextFace())
+ const TopoDS_Face& aFace = SST.CurrentFace();
+ T = SST.Triangulation (aFace, aLoc);
+ if (T.IsNull())
{
- const TopoDS_Face& aFace = SST.CurrentFace();
- T = SST.Triangulation (aFace, aLoc);
- if (T.IsNull())
+ continue;
+ }
+ const gp_Trsf& aTrsf = aLoc.Transformation();
+ Poly_Connect pc (T);
+ // Extracts vertices & normals from nodes
+ const TColgp_Array1OfPnt& aNodes = T->Nodes();
+ const TColgp_Array1OfPnt2d& aUVNodes = T->UVNodes();
+ TColgp_Array1OfDir aNormals (aNodes.Lower(), aNodes.Upper());
+ SST.Normal (aFace, pc, aNormals);
+
+ if (theHasTexels)
+ {
+ BRepTools::UVBounds (aFace, aUmin, aUmax, aVmin, aVmax);
+ dUmax = (aUmax - aUmin);
+ dVmax = (aVmax - aVmin);
+ }
+
+ decal = aPArray->VertexNumber();
+ for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ {
+ p = aNodes (aNodeIter);
+ if (!aLoc.IsIdentity())
{
- continue;
+ p.Transform (aTrsf);
+ aNormals (aNodeIter).Transform (aTrsf);
+ }
+
+ if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
+ {
+ const gp_Pnt2d aTexel = gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes (aNodeIter).X() - aUmin)) / dUmax) / theUVScale.X(),
+ (-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes (aNodeIter).Y() - aVmin)) / dVmax) / theUVScale.Y());
+ aPArray->AddVertex (p, aNormals (aNodeIter), aTexel);
}
- const gp_Trsf& aTrsf = aLoc.Transformation();
- Poly_Connect pc (T);
- // Extracts vertices & normals from nodes
- const TColgp_Array1OfPnt& aNodes = T->Nodes();
- const TColgp_Array1OfPnt2d& aUVNodes = T->UVNodes();
- TColgp_Array1OfDir aNormals (aNodes.Lower(), aNodes.Upper());
- SST.Normal (aFace, pc, aNormals);
-
- if (theHasTexels)
+ else
{
- BRepTools::UVBounds (aFace, aUmin, aUmax, aVmin, aVmax);
- dUmax = (aUmax - aUmin);
- dVmax = (aVmax - aVmin);
+ aPArray->AddVertex (p, aNormals (aNodeIter));
}
+ }
- decal = aPArray->VertexNumber();
- for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
+ // Fill array with vertex and edge visibility info
+ const Poly_Array1OfTriangle& aTriangles = T->Triangles();
+ for (Standard_Integer aTriIter = 1; aTriIter <= T->NbTriangles(); ++aTriIter)
+ {
+ pc.Triangles (aTriIter, t[0], t[1], t[2]);
+ if (SST.Orientation (aFace) == TopAbs_REVERSED)
+ aTriangles (aTriIter).Get (n[0], n[2], n[1]);
+ else
+ aTriangles (aTriIter).Get (n[0], n[1], n[2]);
+
+ gp_Pnt P1 = aNodes (n[0]);
+ gp_Pnt P2 = aNodes (n[1]);
+ gp_Pnt P3 = aNodes (n[2]);
+
+ gp_Vec V1 (P1, P2);
+ if (V1.SquareMagnitude() <= aPreci)
{
- p = aNodes (aNodeIter);
- if (!aLoc.IsIdentity())
- {
- p.Transform (aTrsf);
- aNormals (aNodeIter).Transform (aTrsf);
- }
-
- if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
- {
- const gp_Pnt2d aTexel = gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes (aNodeIter).X() - aUmin)) / dUmax) / theUVScale.X(),
- (-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes (aNodeIter).Y() - aVmin)) / dVmax) / theUVScale.Y());
- aPArray->AddVertex (p, aNormals (aNodeIter), aTexel);
- }
- else
- {
- aPArray->AddVertex (p, aNormals (aNodeIter));
- }
+ continue;
}
-
- // Fill parray with vertex and edge visibillity info
- const Poly_Array1OfTriangle& aTriangles = T->Triangles();
- for (Standard_Integer aTriIter = 1; aTriIter <= T->NbTriangles(); ++aTriIter)
+ gp_Vec V2 (P2, P3);
+ if (V2.SquareMagnitude() <= aPreci)
{
- pc.Triangles (aTriIter, t[0], t[1], t[2]);
- if (SST.Orientation (aFace) == TopAbs_REVERSED)
- aTriangles (aTriIter).Get (n[0], n[2], n[1]);
- else
- aTriangles (aTriIter).Get (n[0], n[1], n[2]);
-
- gp_Pnt P1 = aNodes (n[0]);
- gp_Pnt P2 = aNodes (n[1]);
- gp_Pnt P3 = aNodes (n[2]);
-
- gp_Vec V1 (P1, P2);
- if (V1.SquareMagnitude() <= aPreci)
- {
- continue;
- }
- gp_Vec V2 (P2, P3);
- if (V2.SquareMagnitude() <= aPreci)
- {
- continue;
- }
- gp_Vec V3 (P3, P1);
- if (V3.SquareMagnitude() <= aPreci)
- {
- continue;
- }
- V1.Normalize();
- V2.Normalize();
- V1.Cross (V2);
- if (V1.SquareMagnitude() > aPreci)
- {
- aPArray->AddEdge (n[0] + decal, t[0] == 0);
- aPArray->AddEdge (n[1] + decal, t[1] == 0);
- aPArray->AddEdge (n[2] + decal, t[2] == 0);
- }
+ continue;
+ }
+ gp_Vec V3 (P3, P1);
+ if (V3.SquareMagnitude() <= aPreci)
+ {
+ continue;
+ }
+ V1.Normalize();
+ V2.Normalize();
+ V1.Cross (V2);
+ if (V1.SquareMagnitude() > aPreci)
+ {
+ aPArray->AddEdge (n[0] + decal, t[0] == 0);
+ aPArray->AddEdge (n[1] + decal, t[1] == 0);
+ aPArray->AddEdge (n[2] + decal, t[2] == 0);
}
}
- Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPArray);
}
+ Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPArray);
+
return Standard_True;
}
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)
returns Triangulation from Poly;
-
+
Normal(myclass; aFace: Face from TopoDS;
PC : in out Connect from Poly;
Nor : out Array1OfDir from TColgp);
-
+
end ToolShadedShape from StdPrs;
#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;
+ }
+ }
}
//=======================================================================
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]
set IndexTriangles2 [lsearch ${vfeedback2} Triangles:]
if { ${llength_vfeedback1} < 36 || ${llength_vfeedback2} < 36 || ${IndexTriangles1} < 0 || ${IndexTriangles2} < 0 } {
- puts "Bad format of vfeedback command"
- puts "Faulty ${BugNumber}"
+ puts "Bad format of vfeedback command"
+ puts "Faulty ${BugNumber}"
} else {
- set Triangles1 [lindex ${vfeedback1} ${IndexTriangles1}+1]
- set Triangles2 [lindex ${vfeedback2} ${IndexTriangles1}+1]
- if { ${Triangles1} == 12 && ${Triangles2} == 0 } {
- puts "OK ${BugNumber}"
- } else {
- puts "Faulty ${BugNumber}"
- }
+ set Triangles1 [lindex ${vfeedback1} ${IndexTriangles1}+1]
+ set Triangles2 [lindex ${vfeedback2} ${IndexTriangles1}+1]
+ if { ${Triangles1} == 6 && ${Triangles2} == 0 } {
+ puts "OK ${BugNumber}"
+ } else {
+ puts "Faulty ${BugNumber}"
+ }
}
set only_screen 1
-