1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-06 18:26:22 +03:00

0033056: Visualization - add front face culling option

Added Graphic3d_TypeOfBackfacingModel_FrontCulled enumeration value.
OpenGl_Context::SetFaceCulling() now supports GL_FRONT in addition to GL_BACK.

Added -faceCulling option to vaspects Draw command.
This commit is contained in:
kgv 2022-07-06 23:39:14 +03:00 committed by smoskvin
parent e1d576bf31
commit 9db675b3d6
11 changed files with 183 additions and 42 deletions

View File

@ -54,6 +54,7 @@ static Standard_Byte faceCullToChar (Graphic3d_TypeOfBackfacingModel theMode)
{
case Graphic3d_TypeOfBackfacingModel_Auto: return '0';
case Graphic3d_TypeOfBackfacingModel_BackCulled: return 'B';
case Graphic3d_TypeOfBackfacingModel_FrontCulled: return 'F';
case Graphic3d_TypeOfBackfacingModel_DoubleSided: return '1';
}
return '0';
@ -66,6 +67,7 @@ static Graphic3d_TypeOfBackfacingModel faceCullFromChar (Standard_Byte theMode)
{
case '0': return Graphic3d_TypeOfBackfacingModel_Auto;
case 'B': return Graphic3d_TypeOfBackfacingModel_BackCulled;
case 'F': return Graphic3d_TypeOfBackfacingModel_FrontCulled;
case '1': return Graphic3d_TypeOfBackfacingModel_DoubleSided;
}
return Graphic3d_TypeOfBackfacingModel_Auto;

View File

@ -23,7 +23,8 @@ enum Graphic3d_TypeOfBackfacingModel
Graphic3d_TypeOfBackfacingModel_Auto, //!< automatic back face culling enabled for opaque groups with closed flag
//! (e.g. solids, see Graphic3d_Group::IsClosed())
Graphic3d_TypeOfBackfacingModel_DoubleSided, //!< no culling (double-sided shading)
Graphic3d_TypeOfBackfacingModel_BackCulled, //!< back face culling
Graphic3d_TypeOfBackfacingModel_BackCulled, //!< back face culling
Graphic3d_TypeOfBackfacingModel_FrontCulled, //!< front face culling
// old aliases
Graphic3d_TOBM_AUTOMATIC = Graphic3d_TypeOfBackfacingModel_Auto,
Graphic3d_TOBM_FORCE = Graphic3d_TypeOfBackfacingModel_DoubleSided,

View File

@ -237,7 +237,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
myRenderMode (GL_RENDER),
myShadeModel (GL_SMOOTH),
myPolygonMode (GL_FILL),
myToCullBackFaces (false),
myFaceCulling (Graphic3d_TypeOfBackfacingModel_DoubleSided),
myReadBuffer (0),
myDrawBuffers (0, 7),
myDefaultVao (0),
@ -547,26 +547,35 @@ void OpenGl_Context::SetFrameBufferSRGB (bool theIsFbo, bool theIsFboSRgb)
}
// =======================================================================
// function : SetCullBackFaces
// function : SetFaceCulling
// purpose :
// =======================================================================
void OpenGl_Context::SetCullBackFaces (bool theToEnable)
void OpenGl_Context::SetFaceCulling (Graphic3d_TypeOfBackfacingModel theMode)
{
if (myToCullBackFaces == theToEnable)
if (myFaceCulling == theMode)
{
return;
}
myToCullBackFaces = theToEnable;
if (theToEnable)
if (theMode == Graphic3d_TypeOfBackfacingModel_BackCulled)
{
//glCullFace (GL_BACK); GL_BACK by default
if (myFaceCulling == Graphic3d_TypeOfBackfacingModel_FrontCulled)
{
core11fwd->glCullFace (GL_BACK);
}
core11fwd->glEnable (GL_CULL_FACE);
}
else if (theMode == Graphic3d_TypeOfBackfacingModel_FrontCulled)
{
core11fwd->glCullFace (GL_FRONT);
core11fwd->glEnable (GL_CULL_FACE);
}
else
{
core11fwd->glCullFace (GL_BACK);
core11fwd->glDisable (GL_CULL_FACE);
}
myFaceCulling = theMode;
}
// =======================================================================
@ -3084,7 +3093,7 @@ void OpenGl_Context::DumpJson (Standard_OStream& theOStream, Standard_Integer th
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myRenderMode)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPolygonMode)
OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPolygonOffset)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToCullBackFaces)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myFaceCulling)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myReadBuffer)
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDefaultVao)

View File

@ -803,10 +803,19 @@ public: //! @name methods to alter or retrieve current state
Standard_EXPORT bool SetSampleAlphaToCoverage (bool theToEnable);
//! Return back face culling state.
bool ToCullBackFaces() const { return myToCullBackFaces; }
Graphic3d_TypeOfBackfacingModel FaceCulling() const { return myFaceCulling; }
//! Enable or disable back face culling (glEnable (GL_CULL_FACE)).
Standard_EXPORT void SetCullBackFaces (bool theToEnable);
Standard_EXPORT void SetFaceCulling (Graphic3d_TypeOfBackfacingModel theMode);
//! Return back face culling state.
bool ToCullBackFaces() const { return myFaceCulling == Graphic3d_TypeOfBackfacingModel_BackCulled; }
//! Enable or disable back face culling (glCullFace() + glEnable(GL_CULL_FACE)).
void SetCullBackFaces (bool theToEnable)
{
SetFaceCulling (theToEnable ? Graphic3d_TypeOfBackfacingModel_BackCulled : Graphic3d_TypeOfBackfacingModel_DoubleSided);
}
//! Fetch OpenGl context state. This class tracks value of several OpenGl
//! state variables. Consulting the cached values is quicker than
@ -1155,7 +1164,7 @@ private: //! @name fields tracking current state
Standard_Integer myShadeModel; //!< currently used shade model (glShadeModel)
Standard_Integer myPolygonMode; //!< currently used polygon rasterization mode (glPolygonMode)
Graphic3d_PolygonOffset myPolygonOffset; //!< currently applied polygon offset
bool myToCullBackFaces; //!< back face culling mode enabled state (glIsEnabled (GL_CULL_FACE))
Graphic3d_TypeOfBackfacingModel myFaceCulling; //!< back face culling mode enabled state (glIsEnabled (GL_CULL_FACE))
Standard_Integer myReadBuffer; //!< current read buffer
NCollection_Array1<Standard_Integer>
myDrawBuffers; //!< current draw buffers

View File

@ -1030,10 +1030,9 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
anOutlineProgram->SetUniform (aCtx, anOutlineProgram->GetStateLocation (OpenGl_OCCT_ORTHO_SCALE), anOrthoScale);
aCtx->SetColor4fv (anAspectFace->Aspect()->EdgeColorRGBA());
aCtx->core11fwd->glCullFace (GL_FRONT);
aCtx->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_FrontCulled);
drawArray (theWorkspace, NULL, false);
aCtx->core11fwd->glCullFace (GL_BACK);
aCtx->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_BackCulled);
}
if (isForcedBlend)

View File

@ -255,27 +255,34 @@ const OpenGl_Aspects* OpenGl_Workspace::SetAspects (const OpenGl_Aspects* theAsp
// =======================================================================
const OpenGl_Aspects* OpenGl_Workspace::ApplyAspects (bool theToBindTextures)
{
bool toSuppressBackFaces = myView->BackfacingModel() == Graphic3d_TypeOfBackfacingModel_BackCulled;
if (myView->BackfacingModel() == Graphic3d_TypeOfBackfacingModel_Auto)
//bool toSuppressBackFaces = myView->BackfacingModel() == Graphic3d_TypeOfBackfacingModel_BackCulled;
Graphic3d_TypeOfBackfacingModel aCullFacesMode = myView->BackfacingModel();
if (aCullFacesMode == Graphic3d_TypeOfBackfacingModel_Auto)
{
toSuppressBackFaces = myAspectsSet->Aspect()->FaceCulling() == Graphic3d_TypeOfBackfacingModel_BackCulled;
if (myAspectsSet->Aspect()->FaceCulling() == Graphic3d_TypeOfBackfacingModel_Auto
&& myToAllowFaceCulling)
aCullFacesMode = myAspectsSet->Aspect()->FaceCulling();
if (aCullFacesMode == Graphic3d_TypeOfBackfacingModel_Auto)
{
toSuppressBackFaces = true;
if (myAspectsSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH
|| myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
|| myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Mask
|| myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend
|| (myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_BlendAuto
&& myAspectsSet->Aspect()->FrontMaterial().Transparency() != 0.0f))
aCullFacesMode = Graphic3d_TypeOfBackfacingModel_DoubleSided;
if (myToAllowFaceCulling)
{
// disable culling in case of translucent shading aspect
toSuppressBackFaces = false;
if (myAspectsSet->Aspect()->InteriorStyle() == Aspect_IS_HATCH
|| myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Blend
|| myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_Mask
|| myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_MaskBlend
|| (myAspectsSet->Aspect()->AlphaMode() == Graphic3d_AlphaMode_BlendAuto
&& myAspectsSet->Aspect()->FrontMaterial().Transparency() != 0.0f))
{
// disable culling in case of translucent shading aspect
aCullFacesMode = Graphic3d_TypeOfBackfacingModel_DoubleSided;
}
else
{
aCullFacesMode = Graphic3d_TypeOfBackfacingModel_BackCulled;
}
}
}
}
myGlContext->SetCullBackFaces (toSuppressBackFaces);
myGlContext->SetFaceCulling (aCullFacesMode);
if (myAspectsSet->Aspect() == myAspectsApplied
&& myHighlightStyle == myAspectFaceAppliedWithHL)

View File

@ -493,7 +493,8 @@ void RWGltf_GltfMaterialMap::DefineMaterial (const XCAFPrs_Style& theStyle,
// as both may share the same material having "auto" flag
if (theStyle.Material().IsNull()
|| theStyle.Material()->FaceCulling() == Graphic3d_TypeOfBackfacingModel_Auto
|| theStyle.Material()->FaceCulling() == Graphic3d_TypeOfBackfacingModel_DoubleSided)
|| theStyle.Material()->FaceCulling() == Graphic3d_TypeOfBackfacingModel_DoubleSided
|| theStyle.Material()->FaceCulling() == Graphic3d_TypeOfBackfacingModel_FrontCulled) // front culling flag cannot be exported to glTF
{
myWriter->Key ("doubleSided");
myWriter->Bool (true);

View File

@ -1683,6 +1683,9 @@ struct ViewerTest_AspectsChangeSet
Graphic3d_AlphaMode AlphaMode;
Standard_ShortReal AlphaCutoff;
Standard_Integer ToSetFaceCulling;
Graphic3d_TypeOfBackfacingModel FaceCulling;
Standard_Integer ToSetMaterial;
Graphic3d_NameOfMaterial Material;
TCollection_AsciiString MatName;
@ -1764,6 +1767,8 @@ struct ViewerTest_AspectsChangeSet
ToSetAlphaMode (0),
AlphaMode (Graphic3d_AlphaMode_BlendAuto),
AlphaCutoff (0.5f),
ToSetFaceCulling (0),
FaceCulling (Graphic3d_TypeOfBackfacingModel_Auto),
ToSetMaterial (0),
Material (Graphic3d_NameOfMaterial_DEFAULT),
ToSetShowFreeBoundary (0),
@ -1811,6 +1816,7 @@ struct ViewerTest_AspectsChangeSet
&& ToSetLineWidth == 0
&& ToSetTransparency == 0
&& ToSetAlphaMode == 0
&& ToSetFaceCulling == 0
&& ToSetColor == 0
&& ToSetBackFaceColor == 0
&& ToSetMaterial == 0
@ -2064,6 +2070,15 @@ struct ViewerTest_AspectsChangeSet
theDrawer->ShadingAspect()->Aspect()->SetAlphaMode (AlphaMode, AlphaCutoff);
}
}
if (ToSetFaceCulling != 0)
{
if (ToSetFaceCulling != -1
|| theDrawer->HasOwnShadingAspect())
{
toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
theDrawer->ShadingAspect()->Aspect()->SetFaceCulling (FaceCulling);
}
}
if (ToSetHatch != 0)
{
if (ToSetHatch != -1
@ -2557,6 +2572,47 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
}
}
}
else if (anArg == "-setfaceculling"
|| anArg == "-faceculling")
{
if (++anArgIter >= theArgNb)
{
Message::SendFail() << "Error: wrong syntax at " << anArg;
return 1;
}
aChangeSet->ToSetFaceCulling = 1;
{
TCollection_AsciiString aParam (theArgVec[anArgIter]);
aParam.LowerCase();
if (aParam == "auto")
{
aChangeSet->FaceCulling = Graphic3d_TypeOfBackfacingModel_Auto;
}
else if (aParam == "backculled"
|| aParam == "backcull"
|| aParam == "back")
{
aChangeSet->FaceCulling = Graphic3d_TypeOfBackfacingModel_BackCulled;
}
else if (aParam == "frontculled"
|| aParam == "frontcull"
|| aParam == "front")
{
aChangeSet->FaceCulling = Graphic3d_TypeOfBackfacingModel_FrontCulled;
}
else if (aParam == "doublesided"
|| aParam == "off")
{
aChangeSet->FaceCulling = Graphic3d_TypeOfBackfacingModel_DoubleSided;
}
else
{
Message::SendFail() << "Error: wrong syntax at '" << aParam << "'";
return 1;
}
}
}
else if (anArg == "-setvis"
|| anArg == "-setvisibility"
|| anArg == "-visibility")
@ -3192,6 +3248,8 @@ static Standard_Integer VAspects (Draw_Interpretor& theDI,
aChangeSet->ToSetAlphaMode = -1;
aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
aChangeSet->AlphaCutoff = 0.5f;
aChangeSet->ToSetFaceCulling = -1;
aChangeSet->FaceCulling = Graphic3d_TypeOfBackfacingModel_Auto;
aChangeSet->ToSetColor = -1;
aChangeSet->Color = DEFAULT_COLOR;
//aChangeSet->ToSetBackFaceColor = -1; // should be reset by ToSetColor
@ -6708,7 +6766,7 @@ vsub 0/1 (off/on) [obj] : Subintensity(on/off) of selected objects
vaspects [-noupdate|-update] [name1 [name2 [...]] | -defaults] [-subshapes subname1 [subname2 [...]]]
[-visibility {0|1}]
[-color {ColorName | R G B}] [-unsetColor]
[-backfaceColor Color]
[-backfaceColor Color] [-faceCulling {auto|back|front|doublesided}]
[-material MatName] [-unsetMaterial]
[-transparency Transp] [-unsetTransparency]
[-width LineWidth] [-unsetWidth]

View File

@ -99,6 +99,7 @@ static const char* faceCullToString (Graphic3d_TypeOfBackfacingModel theMode)
{
case Graphic3d_TypeOfBackfacingModel_Auto: return "Auto";
case Graphic3d_TypeOfBackfacingModel_BackCulled: return "BackCulled";
case Graphic3d_TypeOfBackfacingModel_FrontCulled: return "FrontCulled";
case Graphic3d_TypeOfBackfacingModel_DoubleSided: return "DoubleSided";
}
return "";
@ -1161,6 +1162,12 @@ static Standard_Integer XAddVisMaterial (Draw_Interpretor& , Standard_Integer th
{
aMode = Graphic3d_TypeOfBackfacingModel_BackCulled;
}
else if (aCullStr == "frontculled"
|| aCullStr == "frontcull"
|| aCullStr == "front")
{
aMode = Graphic3d_TypeOfBackfacingModel_FrontCulled;
}
else if (aCullStr == "doublesided")
{
aMode = Graphic3d_TypeOfBackfacingModel_DoubleSided;

View File

@ -256,11 +256,14 @@ Standard_Boolean XmlMXCAFDoc_VisMaterialDriver::Paste (const XmlObjMgt_Persisten
aDoubleSidedStr.GetInteger (aDoubleSidedInt);
Standard_ShortReal anAlphaCutOff = 0.5f;
readReal (theSource, ::AlphaCutOff(), anAlphaCutOff);
aMat->SetFaceCulling (aDoubleSidedInt == 1
? Graphic3d_TypeOfBackfacingModel_DoubleSided
: (aDoubleSidedInt == 2
? Graphic3d_TypeOfBackfacingModel_BackCulled
: Graphic3d_TypeOfBackfacingModel_Auto));
switch (aDoubleSidedInt)
{
case 1: aMat->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_DoubleSided); break;
case 2: aMat->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_BackCulled); break;
case 3: aMat->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_FrontCulled); break;
case 0:
default: aMat->SetFaceCulling (Graphic3d_TypeOfBackfacingModel_Auto); break;
}
aMat->SetAlphaMode (alphaModeFromString (theSource.Element().getAttribute (::AlphaMode()).GetString()), anAlphaCutOff);
Quantity_ColorRGBA aBaseColor;
@ -307,11 +310,14 @@ void XmlMXCAFDoc_VisMaterialDriver::Paste (const Handle(TDF_Attribute)& theSourc
XmlObjMgt_SRelocationTable& ) const
{
Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theSource);
Standard_Integer aDoubleSidedInt = aMat->FaceCulling() == Graphic3d_TypeOfBackfacingModel_DoubleSided
? 1
: (aMat->FaceCulling() == Graphic3d_TypeOfBackfacingModel_BackCulled
? 2
: 0);
Standard_Integer aDoubleSidedInt = 0;
switch (aMat->FaceCulling())
{
case Graphic3d_TypeOfBackfacingModel_DoubleSided: aDoubleSidedInt = 1; break;
case Graphic3d_TypeOfBackfacingModel_BackCulled: aDoubleSidedInt = 2; break;
case Graphic3d_TypeOfBackfacingModel_FrontCulled: aDoubleSidedInt = 3; break;
case Graphic3d_TypeOfBackfacingModel_Auto: aDoubleSidedInt = 0; break;
}
theTarget.Element().setAttribute (::IsDoubleSided(), aDoubleSidedInt);
theTarget.Element().setAttribute (::AlphaMode(), alphaModeToString (aMat->AlphaMode()));
writeReal (theTarget, ::AlphaCutOff(), aMat->AlphaCutOff());

View File

@ -0,0 +1,42 @@
puts "========"
puts "0033056: Visualization - add front face culling option"
puts "Check face culling options"
puts "========"
set THE_NB_BOXES 4
set THE_COLORS { ORANGE ORANGE ORANGE ORANGE }
set THE_MODES { AUTO BACK FRONT DOUBLESIDED }
pload MODELING VISUALIZATION
vclear
vinit View1
vcamera -persp -fovy 80
vfront
set x 1
set z 1
for { set i 1 } { $i <= $THE_NB_BOXES } { incr i } {
box b$i [expr $x * 300] 0 [expr $z * 400] 200 300 300
vdisplay -dispMode 1 b$i
vsetcolor b$i [lindex $THE_COLORS [expr $i - 1]]
vaspects b$i -faceCulling [lindex $THE_MODES [expr $i - 1]]
vdrawtext t$i [lindex $THE_MODES [expr $i - 1]] -pos [expr $x * 300] 0 [expr $z * 400 + 300] -height 16 -color RED -font MONOSPACE -aspect BOLD -valign top
incr x
if { $i == 2 } {
set x 1
set z 2
}
}
vfit
vaspects -faceBoundaryDraw 1 -faceBoundaryColor RED
vdump $::imagedir/${::casename}_bnds.png
vaspects -faceBoundaryDraw 0
vclipplane c -equation 0 1 0 -100 -set
vdump $::imagedir/${::casename}_clip.png
vclipplane c off
vdump $::imagedir/${::casename}.png