]> OCCT Git - occt-copy.git/commitdiff
0024437: Efficient HLR visualization based on OpenGL and GLSL
authorasl <asl@opencascade.com>
Thu, 17 May 2018 13:10:30 +0000 (16:10 +0300)
committerabv <abv@opencascade.com>
Tue, 3 Jul 2018 07:42:17 +0000 (10:42 +0300)
New interior style Aspect_IS_OUTLINE is supported for Graphic3d_AspectFillArea3d.
If this style is set, the triangles primitive array is drawn using the outline shader

A new flag theMostAllowedEdgeClass is passed to the methods StdPrs_ShadedShape: Add, FillFaceBoundaries.
It defines the most allowed continuity class of edges that will be included into the presentation.
The edges with more continuity will be ignored.
By default, the value is CN, i.e. all edges are included into the presentation.
The new methods in AIS_Shape: SetMostContinuityClass, MostContinuityClass allows specifying the most allowed continuity class of edges at the level of shape's presentation

17 files changed:
src/AIS/AIS_Shape.cxx
src/AIS/AIS_Shape.hxx
src/Aspect/Aspect_InteriorStyle.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_SetOfShaderPrograms.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_Text.cxx
src/StdPrs/StdPrs_ShadedShape.cxx
src/StdPrs/StdPrs_ShadedShape.hxx
src/ViewerTest/ViewerTest.cxx
tests/bugs/vis/bug24437 [new file with mode: 0644]
tests/bugs/vis/bug29787 [new file with mode: 0644]

index 82b805bc06b96cb5c162070c19dc84de429ee059..148f99154156a24a8ac3605e0b0eb997959e5786 100644 (file)
@@ -90,7 +90,8 @@ AIS_Shape::AIS_Shape(const TopoDS_Shape& theShape)
   myUVRepeat(1.0, 1.0),
   myUVScale (1.0, 1.0),
   myInitAng (0.0),
-  myCompBB (Standard_True)
+  myCompBB (Standard_True),
+  myMostEdgeClass(GeomAbs_CN)
 {
   //
 }
@@ -164,7 +165,8 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
             StdPrs_ShadedShape::Add (aPrs, myshape, myDrawer,
                                      myDrawer->ShadingAspect()->Aspect()->ToMapTexture()
                                  && !myDrawer->ShadingAspect()->Aspect()->TextureMap().IsNull(),
-                                     myUVOrigin, myUVRepeat, myUVScale);
+                                     myUVOrigin, myUVRepeat, myUVScale, StdPrs_Volume_Autodetection,
+                                     myMostEdgeClass);
           }
           catch (Standard_Failure const& anException)
           {
@@ -1192,3 +1194,23 @@ Standard_Boolean AIS_Shape::OwnHLRDeviationAngle ( Standard_Real &  anAngle,
   aPreviousAngle = myDrawer->PreviousHLRDeviationAngle (); 
   return myDrawer->HasOwnHLRDeviationAngle();
 }
+
+//=======================================================================
+//function : SetMostContinuityClass
+//purpose  : 
+//=======================================================================
+
+void AIS_Shape::SetMostContinuityClass(const GeomAbs_Shape theMostAllowedEdgeClass)
+{
+  myMostEdgeClass = theMostAllowedEdgeClass;
+}
+
+//=======================================================================
+//function : MostContinuityClass
+//purpose  : 
+//=======================================================================
+
+GeomAbs_Shape AIS_Shape::MostContinuityClass() const
+{
+  return myMostEdgeClass;
+}
index c6f566f2f5a63bd42e9129291ba644f2f5b31b1c..4a46b7d9fc5038e7966dc0ba66d36ca5246115ea 100644 (file)
@@ -22,6 +22,7 @@
 #include <TopoDS_Shape.hxx>
 #include <Prs3d_Drawer.hxx>
 #include <Prs3d_TypeOfHLR.hxx>
+#include <GeomAbs_Shape.hxx>
 
 //! A framework to manage presentation and selection of shapes.
 //! AIS_Shape is the interactive object which is used the
@@ -214,6 +215,14 @@ public:
   //! the current facing model;
   Standard_EXPORT virtual Standard_Real Transparency() const Standard_OVERRIDE;
 
+  //! Set the most edge continuity class
+  //! @param theMostAllowedEdgeClass the most edge continuity class to be included to presentation 
+  //! (edges with more continuity should be ignored)
+  Standard_EXPORT void SetMostContinuityClass(const GeomAbs_Shape theMostAllowedEdgeClass);
+
+  //! Get the most edge continuity class
+  Standard_EXPORT GeomAbs_Shape MostContinuityClass() const;
+
   //! Return shape type for specified selection mode.
   static TopAbs_ShapeEnum SelectionType (const Standard_Integer theSelMode)
   {
@@ -330,7 +339,7 @@ protected:
   gp_Pnt2d         myUVScale;  //!< UV scale  vector for generating texture coordinates
   Standard_Real    myInitAng;
   Standard_Boolean myCompBB;   //!< if TRUE, then bounding box should be recomputed
-
+  GeomAbs_Shape    myMostEdgeClass; //!< the most edge continuity class to be included to the presentation
 };
 
 DEFINE_STANDARD_HANDLE(AIS_Shape, AIS_InteractiveObject)
index e69a2589f2bd64ebae9682ef2c681c16fc5f9e6c..b197970e3949e13969fad17921ec578f05773644 100644 (file)
@@ -32,7 +32,8 @@ Aspect_IS_HOLLOW,
 Aspect_IS_HATCH,
 Aspect_IS_SOLID,
 Aspect_IS_HIDDENLINE,
-Aspect_IS_POINT
+Aspect_IS_POINT,
+Aspect_IS_OUTLINE
 };
 
 #endif // _Aspect_InteriorStyle_HeaderFile
index 18cbea056d29b53b56bcc7e4a82b1e7bf1e04ac4..00f395befcaa696fdee80822417daa2dad672b74 100644 (file)
@@ -33,6 +33,7 @@
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_AspectFace.hxx>
+#include <OpenGl_View.hxx>
 #include <Graphic3d_TransformUtils.hxx>
 #include <Graphic3d_RenderingParams.hxx>
 
@@ -3447,6 +3448,82 @@ void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
 #endif
 }
 
+// =======================================================================
+// function : PushOrthoScale
+// purpose  :
+// =======================================================================
+void OpenGl_Context::PushOrthoScale (const Handle(OpenGl_Workspace)& theWorkspace)
+{
+  if (!myActiveProgram.IsNull() && !theWorkspace.IsNull())
+  {
+    Handle(Graphic3d_Camera) aCamera = theWorkspace->View()->Camera();
+    Standard_ShortReal aScale = 0.0;
+    if( aCamera->IsOrthographic() )
+      aScale = (Standard_ShortReal)aCamera->Scale();
+    myActiveProgram->SetUniform(this, myActiveProgram->GetStateLocation(OpenGl_OCCT_ORTHO_SCALE), aScale);
+  }
+}
+
+// =======================================================================
+// function : SetIsSilhouettePass
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetIsSilhouettePass (Standard_Boolean isSilhouettePass)
+{
+  if (!myActiveProgram.IsNull() )
+  {
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_IS_SILHOUETTE_PASS),
+      isSilhouettePass ? 1.0f : 0.0f);
+  }
+}
+
+// =======================================================================
+// function : PushBackgroundColor
+// purpose  :
+// =======================================================================
+void OpenGl_Context::PushBackgroundColor (const Handle(OpenGl_Workspace)& theWorkspace)
+{
+  if (!myActiveProgram.IsNull() && !theWorkspace.IsNull())
+  {
+    const Quantity_Color& aBackground = theWorkspace->View()->BackgroundColor().GetRGB();
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_BACKGROUND_COLOR), 
+      OpenGl_Vec3((Standard_ShortReal)aBackground.Red(),
+                  (Standard_ShortReal)aBackground.Green(),
+                  (Standard_ShortReal)aBackground.Blue()));
+  }
+}
+
+// =======================================================================
+// function : SetSilhouetteColor
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetSilhouetteColor (const Quantity_Color& theColor)
+{
+  if (!myActiveProgram.IsNull())
+  {
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_SILHOUETTE_COLOR),
+      OpenGl_Vec3((Standard_ShortReal)theColor.Red(),
+                  (Standard_ShortReal)theColor.Green(),
+                  (Standard_ShortReal)theColor.Blue()));
+  }
+}
+
+// =======================================================================
+// function : SetSilhouetteThickness
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SetSilhouetteThickness (Standard_ShortReal theThickness)
+{
+  if (!myActiveProgram.IsNull())
+  {
+    myActiveProgram->SetUniform(this,
+      myActiveProgram->GetStateLocation(OpenGl_OCCT_SILHOUETTE_THICKNESS), theThickness);
+  }
+}
+
 // =======================================================================
 // function : SetPointSpriteOrigin
 // purpose  :
index 96ac2636ee3ab35e453f87c2c8eb965b3e83c026..b7a8a3f765d0c349860ffc36df589144019846a2 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <NCollection_Shared.hxx>
 
+class OpenGl_Workspace;
+
 //! Forward declarations
 #if defined(__APPLE__)
   #import <TargetConditionals.h>
@@ -722,6 +724,12 @@ public: //! @name methods to alter or retrieve current state
   //! Setup texture matrix to active GLSL program or to FFP global state using glMatrixMode (GL_TEXTURE).
   Standard_EXPORT void SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams);
 
+  Standard_EXPORT void PushOrthoScale (const Handle(OpenGl_Workspace)& theWorkspace);
+  Standard_EXPORT void SetIsSilhouettePass (Standard_Boolean);
+  Standard_EXPORT void PushBackgroundColor (const Handle(OpenGl_Workspace)& theWorkspace);
+  Standard_EXPORT void SetSilhouetteColor (const Quantity_Color&);
+  Standard_EXPORT void SetSilhouetteThickness (Standard_ShortReal);
+
   //! Bind default Vertex Array Object
   Standard_EXPORT void BindDefaultVao();
 
index 71c96fe539d5d0be027b2562397d9e658099a37e..8804b51bcc4d659b6809a622bcfbbfb7fd88d598 100644 (file)
@@ -24,6 +24,7 @@
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_VertexBufferCompat.hxx>
+#include <OpenGl_View.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Graphic3d_TextureParams.hxx>
 #include <NCollection_AlignedAllocator.hxx>
@@ -810,7 +811,39 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
                                                 anAspectFace->Aspect()->AlphaMode(),
                                                 hasVertColor,
                                                 toEnableEnvMap,
-                                                anAspectFace->ShaderProgramRes (aCtx));
+                                                anAspectFace->ShaderProgramRes (aCtx),
+                                                anAspectFace->Aspect()->InteriorStyle());
+
+        if (anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_OUTLINE)
+        {
+          const Graphic3d_Vec4* aFaceColors = !myBounds.IsNull() && !toHilight && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_HIDDENLINE
+            ? myBounds->Colors
+            : NULL;
+
+          aCtx->PushOrthoScale(theWorkspace);
+          aCtx->PushBackgroundColor(theWorkspace);
+          aCtx->SetSilhouetteColor(anAspectFace->Aspect()->EdgeColor());
+
+          Standard_Integer aViewWidth, aViewHeight;
+          theWorkspace->View()->Window()->Size(aViewWidth, aViewHeight);
+          Standard_Integer aMin = aViewWidth < aViewHeight ? aViewWidth : aViewHeight;
+
+          Standard_ShortReal anEdgeWidth = (Standard_ShortReal)anAspectFace->Aspect()->EdgeWidth() / (Standard_ShortReal)aMin;
+          aCtx->SetSilhouetteThickness(anEdgeWidth);
+
+          aCtx->SetIsSilhouettePass(Standard_True);
+          GLboolean isCull = glIsEnabled(GL_CULL_FACE);
+          glEnable(GL_CULL_FACE);
+          glCullFace(GL_FRONT);
+          drawArray(theWorkspace, aFaceColors, hasColorAttrib);
+
+          aCtx->SetIsSilhouettePass(Standard_False);
+          glCullFace(GL_BACK);
+          drawArray(theWorkspace, aFaceColors, hasColorAttrib);
+
+          if (!isCull)
+            glDisable(GL_CULL_FACE);
+        }
         break;
       }
     }
@@ -868,8 +901,9 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
   }
   else
   {
-    if (anAspectFace->Aspect()->ToDrawEdges()
-     || anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
+    if ((anAspectFace->Aspect()->ToDrawEdges()
+        || anAspectFace->Aspect()->InteriorStyle() == Aspect_IS_HIDDENLINE)
+        && anAspectFace->Aspect()->InteriorStyle() != Aspect_IS_OUTLINE)
     {
       const OpenGl_Vec4& anEdgeColor = theWorkspace->EdgeColor();
       drawEdges (anEdgeColor, theWorkspace);
@@ -1026,3 +1060,4 @@ void OpenGl_PrimitiveArray::InitBuffers (const Handle(OpenGl_Context)&        th
 
   setDrawMode (theType);
 }
+
index f04c5471ff4724e9f03947957465cbf55874f995..e4e3fd06d2986993609e897f6d05ea00fefd8d58 100644 (file)
@@ -34,7 +34,8 @@ enum OpenGl_ProgramOptions
   OpenGl_PO_ClipPlanesN = 0x100, //!< handle N clipping planes
   OpenGl_PO_AlphaTest   = 0x200, //!< discard fragment by alpha test (defined by cutoff value)
   OpenGl_PO_WriteOit    = 0x400, //!< write coverage buffer for Blended Order-Independent Transparency
-  OpenGl_PO_NB          = 0x800  //!< overall number of combinations
+  OpenGl_PO_OUTLINE     = 0x800, //!< HLR presentation (outline shader)
+  OpenGl_PO_NB          = 0x1000  //!< overall number of combinations
 };
 
 //! Alias to programs array of predefined length
index a83169c8b11339a419dd9aade678a9bc0c892d92..5bea2eff4a2e36e5e7adf64e009d28b2ce338df3 100644 (file)
@@ -1603,13 +1603,72 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramUnlit (Handle(OpenGl_Sha
     }
   }
 
+  if ((theBits & OpenGl_PO_OUTLINE) != 0)
+  {
+    aSrcVertExtraOut +=
+      EOL"uniform float occOrthoScale;"
+      EOL"uniform float occIsSilhouettePass;"
+      EOL"uniform float occSilhouetteThickness;"
+      ;
+
+    aSrcVertExtraMain +=
+      EOL"  vec3 delta = vec3(0.0, 0.0, 0.0);"
+      EOL"  vec3 pdelta = vec3(0.0, 0.0, 0.0);"
+      EOL"  vec4 proj_normal = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vec4(occNormal, 0.0);"
+      EOL""
+      EOL"  float aShift = occSilhouetteThickness;"
+      EOL"  if (occOrthoScale > 0.0)"
+      EOL"  {"
+      EOL"    if (abs(proj_normal[2]) < 0.25)"
+      EOL"    {"
+      EOL"      float k = 1.0;"
+      EOL"      if (occIsSilhouettePass < 0.1)"
+      EOL"        k = -1.0;"
+      EOL"                 "
+      EOL"      vec3 pn = normalize(vec3(proj_normal.xy, 0.0));"
+      EOL"      pdelta = k * pn * aShift / 2;"
+      EOL"    }"
+      EOL"  }"
+      EOL"  else"
+      EOL"  {"
+      EOL"    if (occIsSilhouettePass > 0.1)"
+      EOL"    {"
+      EOL"      vec4 proj_vertex = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vertex;"
+      EOL"      delta = occNormal.xyz * aShift/2 * proj_vertex.w;"
+      EOL"    }"
+      EOL"  }"
+      EOL"  "
+      EOL"  vertex += vec4(delta, 0.0);"
+      EOL"  vertex[3] = 1.0;"
+      ;
+
+    aSrcVertEndMain +=
+      EOL"gl_Position += vec4(pdelta.xy, 0.0, 0.0);"
+      ;
+
+    aSrcFragExtraOut +=
+      EOL"uniform float occIsSilhouettePass;"
+      EOL"uniform vec3 occBackgroundColor;"
+      EOL"uniform vec3 occSilhouetteColor;"
+      ;
+
+    aSrcFragExtraMain +=
+      EOL"  vec3 aColor = occBackgroundColor;"
+      EOL"  if (occIsSilhouettePass > 0.1)"
+      EOL"    aColor = occSilhouetteColor;"
+      ;
+
+    aSrcFragWriteOit = EOL"  occSetFragColor(vec4(aColor, 1.0));";
+  }
+
   aSrcVert =
       aSrcVertExtraFunc
     + aSrcVertExtraOut
     + EOL"void main()"
       EOL"{"
+      EOL"  vec4 vertex = occVertex;"
     + aSrcVertExtraMain
-    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
+    + EOL"  gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * vertex;"
     + aSrcVertEndMain
     + EOL"}";
 
index 7c423e00664f9cc1472a6fbf22cd035665783801..83ff3f5da3c3aaf2ce8da3e19d880fa127b17129 100644 (file)
@@ -87,7 +87,8 @@ public:
                                     const Graphic3d_AlphaMode           theAlphaMode,
                                     const Standard_Boolean              theHasVertColor,
                                     const Standard_Boolean              theEnableEnvMap,
-                                    const Handle(OpenGl_ShaderProgram)& theCustomProgram)
+                                    const Handle(OpenGl_ShaderProgram)& theCustomProgram,
+                                    const Aspect_InteriorStyle          theStyle)
   {
     if (!theCustomProgram.IsNull()
      || myContext->caps->ffpEnable)
@@ -99,7 +100,7 @@ public:
                                                         && (theTextures.IsNull() || theTextures->IsModulate())
                                                         ? theShadingModel
                                                         : Graphic3d_TOSM_UNLIT;
-    const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap);
+    const Standard_Integer        aBits    = getProgramBits (theTextures, theAlphaMode, theHasVertColor, theEnableEnvMap, theStyle);
     Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (aShadeModelOnFace, aBits);
     return bindProgramWithState (aProgram);
   }
@@ -401,7 +402,8 @@ protected:
   Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
                                    Graphic3d_AlphaMode theAlphaMode,
                                    Standard_Boolean theHasVertColor,
-                                   Standard_Boolean theEnableEnvMap)
+                                   Standard_Boolean theEnableEnvMap,
+                                   Aspect_InteriorStyle theStyle=Aspect_IS_EMPTY)
 
   {
     Standard_Integer aBits = 0;
@@ -444,6 +446,11 @@ protected:
     {
       aBits |= OpenGl_PO_WriteOit;
     }
+
+    if (theStyle == Aspect_IS_OUTLINE)
+    {
+      aBits |= OpenGl_PO_OUTLINE;
+    }
     return aBits;
   }
 
@@ -452,7 +459,8 @@ protected:
                                                Standard_Integer theBits)
   {
     if (theShadingModel == Graphic3d_TOSM_UNLIT
-     || (theBits & OpenGl_PO_TextureEnv) != 0)
+     || (theBits & OpenGl_PO_TextureEnv) != 0
+     || (theBits & OpenGl_PO_OUTLINE) != 0)
     {
       // If environment map is enabled lighting calculations are
       // not needed (in accordance with default OCCT behavior)
index 784dc528ab739c8a7985e9f9b99ec131092d2b0c..e9039714b6dda78b2bb1f5a6cdf967d38c25d738 100755 (executable)
@@ -74,7 +74,13 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occOitDepthFactor",     // OpenGl_OCCT_OIT_DEPTH_FACTOR
 
   "occTexTrsf2d",          // OpenGl_OCCT_TEXTURE_TRSF2D
-  "occPointSize"           // OpenGl_OCCT_POINT_SIZE
+  "occPointSize",          // OpenGl_OCCT_POINT_SIZE
+
+  "occOrthoScale",         // OpenGl_OCCT_ORTHO_SCALE
+  "occIsSilhouettePass",   // OpenGl_OCCT_IS_SILHOUETTE_PASS
+  "occBackgroundColor",    // OpenGl_OCCT_BACKGROUND_COLOR
+  "occSilhouetteColor",    // OpenGl_OCCT_SILHOUETTE_COLOR
+  "occSilhouetteThickness" // OpenGl_OCCT_SILHOUETTE_THICKNESS
 };
 
 namespace
index 87941ff0b3a40a582382086a8c41037a6cc9b23a..639921f7360d157fa63ad9486b9e5756af581849 100755 (executable)
@@ -74,6 +74,13 @@ enum OpenGl_StateVariable
   OpenGl_OCCT_TEXTURE_TRSF2D,
   OpenGl_OCCT_POINT_SIZE,
 
+  // Parameters of outline (silhouette) shader
+  OpenGl_OCCT_ORTHO_SCALE,
+  OpenGl_OCCT_IS_SILHOUETTE_PASS,
+  OpenGl_OCCT_BACKGROUND_COLOR,
+  OpenGl_OCCT_SILHOUETTE_COLOR,
+  OpenGl_OCCT_SILHOUETTE_THICKNESS,
+
   // DON'T MODIFY THIS ITEM (insert new items before it)
   OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
 };
index 9f162cc35b5f585e5957bf7207bbff3289ee452c..bf92c354c7d936d736d4ed1766737b3f8a51544f 100644 (file)
@@ -761,7 +761,7 @@ void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
   // bind unlit program
   theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Graphic3d_TOSM_UNLIT,
                                             Graphic3d_AlphaMode_Opaque, Standard_False, Standard_False,
-                                            Handle(OpenGl_ShaderProgram)());
+                                            Handle(OpenGl_ShaderProgram)(), Aspect_IS_SOLID);
 
 #if !defined(GL_ES_VERSION_2_0)
   if (theCtx->core11 != NULL
index e098fc47e684ffc5d6616dc08fe28b7c02e31533..b182a672678864eb83b2ef42489b3d3aeff137ae 100644 (file)
@@ -301,7 +301,8 @@ namespace
   }
 
   //! Compute boundary presentation for faces of the shape.
-  static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries (const TopoDS_Shape& theShape)
+  static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries
+    (const TopoDS_Shape& theShape, const GeomAbs_Shape theMostAllowedEdgeClass)
   {
     // collection of all triangulation nodes on edges
     // for computing boundaries presentation
@@ -341,6 +342,16 @@ namespace
       }
 
       const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
+      if (anEdgeIter.Value().Extent() > 1)
+      {
+        TopTools_ListIteratorOfListOfShape anIter2(anEdgeIter.Value());
+        anIter2.Next();
+        const TopoDS_Face& aFace2 = TopoDS::Face(anIter2.Value());
+        GeomAbs_Shape aShape = BRep_Tool::Continuity(anEdge, aFace, aFace2);
+        if (aShape > theMostAllowedEdgeClass)
+          continue;
+      }
+
       Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf);
       if (!anEdgePoly.IsNull()
         && anEdgePoly->Nodes().Length() >= 2)
@@ -384,6 +395,16 @@ namespace
       }
 
       const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
+      if (anEdgeIter.Value().Extent() > 1)
+      {
+        TopTools_ListIteratorOfListOfShape anIter2(anEdgeIter.Value());
+        anIter2.Next();
+        const TopoDS_Face& aFace2 = TopoDS::Face(anIter2.Value());
+        GeomAbs_Shape aShape = BRep_Tool::Continuity(anEdge, aFace, aFace2);
+        if (aShape > theMostAllowedEdgeClass)
+          continue;
+      }
+
       Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf);
       if (anEdgePoly.IsNull()
        || anEdgePoly->Nodes().Length () < 2)
@@ -501,11 +522,12 @@ void StdPrs_ShadedShape::ExploreSolids (const TopoDS_Shape&    theShape,
 void StdPrs_ShadedShape::Add (const Handle(Prs3d_Presentation)& thePrs,
                               const TopoDS_Shape&               theShape,
                               const Handle(Prs3d_Drawer)&       theDrawer,
-                              const StdPrs_Volume               theVolume)
+                              const StdPrs_Volume               theVolume,
+                              const GeomAbs_Shape               theMostAllowedEdgeClass)
 {
   gp_Pnt2d aDummy;
   StdPrs_ShadedShape::Add (thePrs, theShape, theDrawer,
-                           Standard_False, aDummy, aDummy, aDummy, theVolume);
+                           Standard_False, aDummy, aDummy, aDummy, theVolume, theMostAllowedEdgeClass);
 }
 
 // =======================================================================
@@ -519,7 +541,8 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
                               const gp_Pnt2d&                    theUVOrigin,
                               const gp_Pnt2d&                    theUVRepeat,
                               const gp_Pnt2d&                    theUVScale,
-                              const StdPrs_Volume                theVolume)
+                              const StdPrs_Volume                theVolume,
+                              const GeomAbs_Shape                theMostAllowedEdgeClass)
 {
   if (theShape.IsNull())
   {
@@ -578,7 +601,7 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs,
 
   if (theDrawer->FaceBoundaryDraw())
   {
-    Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape);
+    Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape, theMostAllowedEdgeClass);
     if (!aBndSegments.IsNull())
     {
       Handle(Graphic3d_AspectLine3d) aBoundaryAspect = theDrawer->FaceBoundaryAspect()->Aspect();
@@ -606,9 +629,10 @@ Handle(Graphic3d_ArrayOfTriangles) StdPrs_ShadedShape::FillTriangles (const Topo
 // function : FillFaceBoundaries
 // purpose  :
 // =======================================================================
-Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape)
+Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape,
+                                                                          const GeomAbs_Shape theMostAllowedEdgeClass)
 {
-  return fillFaceBoundaries (theShape);
+  return fillFaceBoundaries (theShape, theMostAllowedEdgeClass);
 }
 
 // =======================================================================
index cbb2a7df75b91d3d2181620c6035cd1ff2671407..dc5bdcc12f8f78a9c753720014c2d365973e25dc 100644 (file)
@@ -25,6 +25,7 @@
 #include <Prs3d_Drawer.hxx>
 #include <StdPrs_Volume.hxx>
 #include <Standard_Boolean.hxx>
+#include <GeomAbs_Shape.hxx>
 
 class Graphic3d_ArrayOfSegments;
 class Graphic3d_ArrayOfTriangles;
@@ -43,13 +44,27 @@ public:
   //! @param theVolumeType defines the way how to interpret input shapes - as Closed volumes (to activate back-face
   //! culling and capping plane algorithms), as Open volumes (shells or solids with holes)
   //! or to perform Autodetection (would split input shape into two groups)
-  Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation, const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer, const StdPrs_Volume theVolume = StdPrs_Volume_Autodetection);
+  //! @param theMostAllowedEdgeClass the most edge continuity class to be included to result (edges with more continuity should be ignored)
+  Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation,
+                                   const TopoDS_Shape& theShape,
+                                   const Handle(Prs3d_Drawer)& theDrawer,
+                                   const StdPrs_Volume theVolume = StdPrs_Volume_Autodetection,
+                                   const GeomAbs_Shape theMostAllowedEdgeClass = GeomAbs_CN);
   
   //! Shades <theShape> with texture coordinates.
   //! @param theVolumeType defines the way how to interpret input shapes - as Closed volumes (to activate back-face
   //! culling and capping plane algorithms), as Open volumes (shells or solids with holes)
   //! or to perform Autodetection (would split input shape into two groups)
-  Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation, const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer, const Standard_Boolean theHasTexels, const gp_Pnt2d& theUVOrigin, const gp_Pnt2d& theUVRepeat, const gp_Pnt2d& theUVScale, const StdPrs_Volume theVolume = StdPrs_Volume_Autodetection);
+  //! @param theMostAllowedEdgeClass the most edge continuity class to be included to result (edges with more continuity should be ignored)
+  Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation,
+                                   const TopoDS_Shape& theShape,
+                                   const Handle(Prs3d_Drawer)& theDrawer,
+                                   const Standard_Boolean theHasTexels,
+                                   const gp_Pnt2d& theUVOrigin,
+                                   const gp_Pnt2d& theUVRepeat,
+                                   const gp_Pnt2d& theUVScale,
+                                   const StdPrs_Volume theVolume = StdPrs_Volume_Autodetection,
+                                   const GeomAbs_Shape theMostAllowedEdgeClass = GeomAbs_CN);
   
   //! Searches closed and unclosed subshapes in shape structure and puts them
   //! into two compounds for separate processing of closed and unclosed sub-shapes
@@ -90,8 +105,9 @@ public:
 
   //! Define primitive array of boundary segments for specified shape.
   //! @param theShape segments array or NULL if specified face does not have computed triangulation
-  Standard_EXPORT static Handle(Graphic3d_ArrayOfSegments) FillFaceBoundaries (const TopoDS_Shape& theShape);
-
+  //! @param theMostAllowedEdgeClass the most edge continuity class to be included to result (edges with more continuity should be ignored)
+  Standard_EXPORT static Handle(Graphic3d_ArrayOfSegments) FillFaceBoundaries
+    (const TopoDS_Shape& theShape, const GeomAbs_Shape theMostAllowedEdgeClass = GeomAbs_CN);
 };
 
 #endif // _StdPrs_ShadedShape_HeaderFile
index 6f53cd3ada957cb972b1e905f8bb618871f2438f..05d0e770606286a8dd6197d9e1a1f320a7305c3e 100644 (file)
@@ -1575,14 +1575,18 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI,
   {
     anInterStyle = Aspect_IS_POINT;
   }
+  else if (aStyleArg == "outline")
+  {
+    anInterStyle = Aspect_IS_OUTLINE;
+  }
   else
   {
     const Standard_Integer anIntStyle = aStyleArg.IntegerValue();
     if (anIntStyle < Aspect_IS_EMPTY
-     || anIntStyle > Aspect_IS_POINT)
+     || anIntStyle > Aspect_IS_OUTLINE)
     {
       std::cout << "Error: style must be within a range [0 (Aspect_IS_EMPTY), "
-                << Aspect_IS_POINT << " (Aspect_IS_POINT)]\n";
+                << Aspect_IS_OUTLINE << " (Aspect_IS_OUTLINE)]\n";
       return 1;
     }
     anInterStyle = (Aspect_InteriorStyle )anIntStyle;
@@ -1615,6 +1619,72 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI,
   return 0;
 }
 
+//==============================================================================
+//function : VSetMostCont
+//purpose  : sets the most continuity class of edges in presentation
+//==============================================================================
+static int VSetMostCont(Draw_Interpretor& theDI,
+  Standard_Integer  theArgNb,
+  const char**      theArgVec)
+{
+  const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
+  ViewerTest_AutoUpdater anUpdateTool(aCtx, ViewerTest::CurrentView());
+  if (aCtx.IsNull())
+  {
+    std::cerr << "Error: no active view!\n";
+    return 1;
+  }
+
+  if (theArgNb != 3)
+  {
+    std::cout << "Error: wrong number of arguments! See usage:\n";
+    theDI.PrintHelp(theArgVec[0]);
+    return 1;
+  }
+
+  TCollection_AsciiString aName = theArgVec[1];
+  TCollection_AsciiString aClassArg = theArgVec[2];
+  aClassArg.LowerCase();
+
+  GeomAbs_Shape aClass = GeomAbs_CN;
+  if (aClassArg == "c0")
+    aClass = GeomAbs_C0;
+  else if (aClassArg == "c1")
+    aClass = GeomAbs_C1;
+  else if (aClassArg == "c2")
+    aClass = GeomAbs_C2;
+  else if (aClassArg == "c3")
+    aClass = GeomAbs_C3;
+  else if (aClassArg == "cn")
+    aClass = GeomAbs_CN;
+  else
+  {
+    std::cout << "Error: incorrect class! See usage:\n";
+    theDI.PrintHelp(theArgVec[0]);
+    return 1;
+  }
+
+  if (!aName.IsEmpty()
+    && !GetMapOfAIS().IsBound2(aName))
+  {
+    std::cout << "Error: object " << aName << " is not displayed!\n";
+    return 1;
+  }
+
+  for (ViewTest_PrsIter anIter(aName); anIter.More(); anIter.Next())
+  {
+    const Handle(AIS_Shape)& aShape = Handle(AIS_Shape)::DownCast(anIter.Current());
+    if (!aShape.IsNull())
+    {
+      aShape->SetMostContinuityClass(aClass);
+      aCtx->RecomputePrsOnly(aShape, Standard_False, Standard_True);
+    }
+  }
+  return 0;
+}
+
+
+
 //! Auxiliary structure for VAspects
 struct ViewerTest_AspectsChangeSet
 {
@@ -6070,6 +6140,12 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
       "\n\t\t: Where style is: 0 = EMPTY, 1 = HOLLOW, 2 = HATCH, 3 = SOLID, 4 = HIDDENLINE.",
                  __FILE__,VSetInteriorStyle,group);
 
+  theCommands.Add("vsetmostcont",
+    "vsetmostcont : ObjectName class"
+    "- sets the most continuity class of edges in presentation",
+    "\n\t\t: Where class is c0, c1, c2, c3, cn"
+    __FILE__, VSetMostCont, group);
+
   theCommands.Add("vsensdis",
       "vsensdis : Display active entities (sensitive entities of one of the standard types corresponding to active selection modes)."
       "\n\t\t: Standard entity types are those defined in Select3D package:"
diff --git a/tests/bugs/vis/bug24437 b/tests/bugs/vis/bug24437
new file mode 100644 (file)
index 0000000..4b2ac3a
--- /dev/null
@@ -0,0 +1,36 @@
+puts "========"
+puts "0024437: Efficient HLR visualization based on OpenGL and GLSL"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vsetcolorbg 220 220 220
+
+psphere sph 1.0
+
+box b 1 2 3
+ttranslate b 2 -2 -2
+
+pcylinder cyl 1.0 1.0
+ttranslate cyl 4.2 0 0 
+
+vdisplay -dispMode 1 b
+vsetinteriorstyle b outline
+vshowfaceboundary b 1 255 0 0 1
+vsetedgetype b -color 255 0 0
+vfit
+
+vdisplay -dispMode 1 sph
+vsetinteriorstyle sph outline
+vshowfaceboundary sph 1 255 0 0 1
+vsetedgetype sph -color 255 0 0
+vfit
+
+vdisplay -dispMode 1 cyl
+vsetinteriorstyle cyl outline
+vshowfaceboundary cyl 1 255 0 0 1
+vsetedgetype cyl -color 255 0 0
+vfit
diff --git a/tests/bugs/vis/bug29787 b/tests/bugs/vis/bug29787
new file mode 100644 (file)
index 0000000..bbfe712
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "0029787: Avoid in presentation edges of certain continuity class"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vsetcolorbg 255 255 255
+
+psphere sph1 1.0
+psphere sph2 1.0
+psphere sph3 1.0
+
+ttranslate sph2 4.0 0.0 0.0
+ttranslate sph3 8.0 0.0 0.0
+
+vdisplay -dispMode 0 sph1
+vdisplay -dispMode 1 sph2
+vshowfaceboundary sph2 1 255 0 0
+vdisplay -dispMode 1 sph3
+vshowfaceboundary sph3 1 255 0 0
+vsetmostcont sph3 c2
+vfit