]> OCCT Git - occt.git/commitdiff
0030979: Visualization - introduce customized grid presentations CR0_ALC_OCCT781
authormzernova <mzernova@opencascade.com>
Tue, 25 Aug 2020 10:17:04 +0000 (11:17 +0100)
committermzernova <mzernova@opencascade.com>
Wed, 4 Jun 2025 12:57:19 +0000 (13:57 +0100)
23 files changed:
src/AIS/AIS_ViewController.cxx
src/Aspect/Aspect_Grid.cxx
src/Aspect/Aspect_Grid.hxx
src/Aspect/Aspect_GridParams.hxx [new file with mode: 0644]
src/Aspect/Aspect_RectangularGrid.cxx
src/Aspect/FILES
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_Camera.hxx
src/Graphic3d/Graphic3d_ShaderManager.cxx
src/Graphic3d/Graphic3d_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/V3d/V3d_CircularGrid.cxx
src/V3d/V3d_CircularGrid.hxx
src/V3d/V3d_RectangularGrid.cxx
src/V3d/V3d_RectangularGrid.hxx
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/grid/ortho [new file with mode: 0644]
tests/v3d/grid/persp [new file with mode: 0644]

index 78e70074715c324d7c0caa53c61efcd7951d0e40..4e67838dfc6f697b0fefc8e8d5936d716c1c6d8a 100644 (file)
@@ -1503,6 +1503,10 @@ void AIS_ViewController::handlePanning (const Handle(V3d_View)& theView)
   AbortViewAnimation();
 
   const Handle(Graphic3d_Camera)& aCam = theView->Camera();
+  aCam->SetPanningVector(aCam->PanningVector() +
+                         gp_Vec2d(theView->Convert(myGL.Panning.Delta.x()),
+                                  theView->Convert(myGL.Panning.Delta.y())));
+
   if (aCam->IsOrthographic()
   || !hasPanningAnchorPoint())
   {
@@ -1721,6 +1725,7 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView,
     myCamStartOpToEye    = gp_Vec (myRotatePnt3d, aCam->Eye()).Transformed (aTrsf);
     myCamStartOpToCenter = gp_Vec (myRotatePnt3d, aCam->Center()).Transformed (aTrsf);
 
+    aCam->SetRotationPoint (myRotatePnt3d);
     theView->Invalidate();
   }
 
@@ -1833,6 +1838,7 @@ void AIS_ViewController::handleViewRotation (const Handle(V3d_View)& theView,
     const gp_Quaternion aRot = aTrsf.GetRotation();
     double aRollDummy = 0.0;
     aRot.GetEulerAngles (gp_YawPitchRoll, myRotateStartYawPitchRoll[0], myRotateStartYawPitchRoll[1], aRollDummy);
+    aCam->SetRotationPoint (gp::Origin());
   }
   if (toRotateAnyway)
   {
@@ -2259,6 +2265,12 @@ void AIS_ViewController::handleCameraActions (const Handle(AIS_InteractiveContex
     myGL.Orientation.ToFitAll = false;
   }
 
+  if (theView->Viewer()->Grid()->IsActive()
+   && theView->Viewer()->GridEcho())
+  {
+    theView->Viewer()->Grid()->Update();
+  }
+
   if (myGL.IsNewGesture)
   {
     if (myAnchorPointPrs1->HasInteractiveContext())
index eed3460bd8babc80b6bd6355f6b4749e48f9aaab..2bd2aa1d6cfb3cb5035565fc723ee7a064e7e0f8 100644 (file)
 IMPLEMENT_STANDARD_RTTIEXT(Aspect_Grid,Standard_Transient)
 
 Aspect_Grid::Aspect_Grid (const Standard_Real theXOrigin,
-                                           const Standard_Real theYOrigin,
-                                           const Standard_Real theAngle,
-                                           const Quantity_Color& theColor,
-                                           const Quantity_Color& theTenthColor)
+                          const Standard_Real theYOrigin,
+                          const Standard_Real theAngle,
+                          const Quantity_Color& theColor,
+                          const Quantity_Color& theTenthColor)
 : myRotationAngle (theAngle),
   myXOrigin (theXOrigin),
   myYOrigin (theYOrigin),
@@ -60,7 +60,7 @@ void Aspect_Grid::Rotate (const Standard_Real theAngle)
 }
 
 void Aspect_Grid::Translate (const Standard_Real theDx,
-                                                    const Standard_Real theDy)
+                             const Standard_Real theDy)
 {
   myXOrigin += theDx;
   myYOrigin += theDy;
@@ -69,7 +69,7 @@ void Aspect_Grid::Translate (const Standard_Real theDx,
 }
 
 void Aspect_Grid::SetColors (const Quantity_Color& theColor,
-                                              const Quantity_Color& theTenthColor)
+                             const Quantity_Color& theTenthColor)
 {
   myColor = theColor;
   myTenthColor = theTenthColor;
@@ -77,16 +77,16 @@ void Aspect_Grid::SetColors (const Quantity_Color& theColor,
 }
 
 void Aspect_Grid::Colors (Quantity_Color& theColor,
-                                           Quantity_Color& theTenthColor) const
+                          Quantity_Color& theTenthColor) const
 {
   theColor = myColor;
   theTenthColor = myTenthColor;
 }
 
 void Aspect_Grid::Hit (const Standard_Real theX,
-                                        const Standard_Real theY,
-                                        Standard_Real& theGridX,
-                                        Standard_Real& theGridY) const
+                       const Standard_Real theY,
+                       Standard_Real& theGridX,
+                       Standard_Real& theGridY) const
 {
   if (myIsActive)
   {
index cce1715371bd6c8c7375ffec18aa678da5fc1825..ab8e76eab1bc53ce0abf3b00e94e991631805ce0 100644 (file)
@@ -86,6 +86,9 @@ public:
 
   //! Display the grid at screen.
   Standard_EXPORT virtual void Display() = 0;
+
+  //! Update grid presentation
+  Standard_EXPORT virtual void Update() = 0;
   
   //! Erase the grid from screen.
   Standard_EXPORT virtual void Erase() const = 0;
diff --git a/src/Aspect/Aspect_GridParams.hxx b/src/Aspect/Aspect_GridParams.hxx
new file mode 100644 (file)
index 0000000..de3068f
--- /dev/null
@@ -0,0 +1,67 @@
+// Created on: 1995-03-02
+// Created by: Jean-Louis Frenkel
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Aspect_GridParams_HeaderFile
+#define _Aspect_GridParams_HeaderFile
+
+#include <Quantity_Color.hxx>
+#include <gp_Pnt.hxx>
+
+class Aspect_GridParams
+{
+public:
+
+  //! Constructor.
+  Aspect_GridParams()
+  : myColor (0.8, 0.8, 0.8, Quantity_TOC_RGB),
+    myPosition (0.0, 0.0, 0.0),
+    myScale (0.01),
+    myLineThickness (0.01),
+    myIsBackground (false),
+    myIsDrawAxis (true),
+    myIsInfinity (false)
+  {}
+
+  //! Getters
+  Standard_Boolean IsBackground() const { return myIsBackground; }
+  Standard_Boolean IsDrawAxis() const { return myIsDrawAxis; }
+  const Quantity_Color& Color() const { return myColor; }
+  Standard_Real Scale() const { return myScale; }
+  Standard_Boolean IsInfinity() const { return myIsInfinity; }
+  const gp_Pnt& Position() const { return myPosition; }
+  Standard_Real LineThickness() const { return myLineThickness; }
+
+  //! Setters
+  void SetIsBackground (Standard_Boolean theValue) { myIsBackground = theValue; }
+  void SetIsDrawAxis (Standard_Boolean theValue) { myIsDrawAxis = theValue; }
+  void SetColor (const Quantity_Color& theColor) { myColor = theColor; }
+  void SetScale (Standard_Real theScale) { myScale = theScale; }
+  void SetIsInfinity (Standard_Boolean theValue) { myIsInfinity = theValue; }
+  void SetPosition (const gp_Pnt& thePosition) { myPosition = thePosition; }
+  void SetLineThickness (Standard_Real theThickness) { myLineThickness = theThickness; }
+
+private:
+
+  Quantity_Color   myColor;
+  gp_Pnt           myPosition;
+  Standard_Real    myScale;
+  Standard_Real    myLineThickness;
+  Standard_Boolean myIsBackground;
+  Standard_Boolean myIsDrawAxis;
+  Standard_Boolean myIsInfinity;
+};
+
+#endif // _Aspect_GridParams_HeaderFile
index ad8712fafdadd56a40a5615ffc6548d9daadcb7e..a6263ec5b00fa5d306e13dc690f48a1baf19f87c 100644 (file)
@@ -27,8 +27,11 @@ Aspect_RectangularGrid::Aspect_RectangularGrid(
                                const Standard_Real aFirstAngle,
                                const Standard_Real aSecondAngle,
                                const Standard_Real aRotationAngle)
-:Aspect_Grid(anXOrigin,anYOrigin,aRotationAngle),myXStep(aXStep),myYStep(aYStep),myFirstAngle(aFirstAngle),mySecondAngle(aSecondAngle)
-
+: Aspect_Grid (anXOrigin,anYOrigin,aRotationAngle),
+  myXStep (aXStep),
+  myYStep (aYStep),
+  myFirstAngle (aFirstAngle),
+  mySecondAngle (aSecondAngle)
 {
   Standard_NumericError_Raise_if(!CheckAngle (aFirstAngle,mySecondAngle),
                                  "networks are parallel");
index b1c7fa3f980ad0fc43ea2169d3f1976f7b9647f7..7152c787905d115c02bc47b99fe458290c296305 100755 (executable)
@@ -25,6 +25,7 @@ Aspect_GraphicsLibrary.hxx
 Aspect_Grid.cxx
 Aspect_Grid.hxx
 Aspect_GridDrawMode.hxx
+Aspect_GridParams.hxx
 Aspect_GridType.hxx
 Aspect_NeutralWindow.cxx
 Aspect_NeutralWindow.hxx
index 5fe56d44677ac8313f6229f37303f7bdd88ff520..911af98f4391923485794432603f375a8d0fa887 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef _Graphic3d_CView_HeaderFile
 #define _Graphic3d_CView_HeaderFile
 
+#include <Aspect_GridParams.hxx>
 #include <Aspect_RenderingContext.hxx>
 #include <Aspect_SkydomeBackground.hxx>
 #include <Aspect_Window.hxx>
@@ -530,6 +531,12 @@ public: //! @name obsolete Graduated Trihedron functionality
   //! Erases Graduated Trihedron.
   virtual void GraduatedTrihedronErase() {}
 
+  //! Displays Grid.
+  virtual void GridDisplay (const Aspect_GridParams& theGridParams) { (void)theGridParams; }
+
+  //! Erases Grid.
+  virtual void GridErase() {}
+
   //! Sets minimum and maximum points of scene bounding box for Graduated Trihedron stored in graphic view object.
   //! @param theMin [in] the minimum point of scene.
   //! @param theMax [in] the maximum point of scene.
index aeebc7cbf61f839f7ee111ae2eb61231d7a0045d..2d93ecd9f78b4f6ec38b1083934d0f04ec6103c0 100644 (file)
@@ -275,6 +275,31 @@ public:
   //! @param theCenter [in] the point where the camera looks at.
   Standard_EXPORT void SetCenter (const gp_Pnt& theCenter);
 
+  //! Get active rotation center of the camera (gravity point).
+  //! @return the gravity point.
+  gp_Pnt RotationPoint() const
+  {
+    return myRotationPoint;
+  }
+
+  //! Sets active rotation center of the camera (gravity point).
+  //! @param theRotationPoint [in] the gravity point.
+  void SetRotationPoint (const gp_Pnt& theRotationPoint)
+  {
+    myRotationPoint = theRotationPoint;
+  };
+
+  //! Get panning translation.
+  //! @return the panning translation.
+  gp_Vec2d PanningVector() const { return myPanningVector; }
+
+  //! Sets panning translation.
+  //! @param thePanningVector [in] the panning translation.
+  void SetPanningVector(const gp_Vec2d &thePanningVector)
+  {
+    myPanningVector = thePanningVector;
+  };
+
   //! Get distance of Eye from camera Center.
   //! @return the distance.
   Standard_Real Distance() const { return myDistance; }
@@ -839,6 +864,8 @@ private:
   gp_Dir        myUp;       //!< Camera up direction vector
   gp_Dir        myDirection;//!< Camera view direction (from eye)
   gp_Pnt        myEye;      //!< Camera eye position
+  gp_Pnt        myRotationPoint;
+  gp_Vec2d      myPanningVector;
   Standard_Real myDistance; //!< distance from Eye to Center
 
   gp_XYZ myAxialScale; //!< World axial scale.
index 7b15254330f3e214f01282aa00b2ea9cda972a7d..4434ef7fe79989f44a5fe6ae1e4200d05ef92543 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2013-2021 OPEN CASCADE SAS
+// Copyright (c) 2013-2021 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
@@ -2187,3 +2187,111 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getColoredQuadProgram()
 
   return aProgSrc;
 }
+
+Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getGridProgram() const
+{
+  Handle(Graphic3d_ShaderProgram) aProgSrc = new Graphic3d_ShaderProgram();
+
+  Graphic3d_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
+  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 NearPoint", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 FarPoint", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+  aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 MVP", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("float uZNear", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("float uZFar", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("float uScale", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("float uThickness", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("bool uIsDrawAxis", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("bool uIsBackground", Graphic3d_TOS_FRAGMENT));
+  aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 uColor", Graphic3d_TOS_FRAGMENT));
+
+  TCollection_AsciiString aSrcVert = TCollection_AsciiString()
+  + EOL"vec3 gridPlane[6] = vec3[] (vec3( 1.0,  1.0, 0.0), vec3(-1.0, -1.0, 0.0), vec3(-1.0,  1.0, 0.0),"
+    EOL"                            vec3(-1.0, -1.0, 0.0), vec3( 1.0,  1.0, 0.0), vec3( 1.0, -1.0, 0.0));"
+
+    EOL"vec3 UnprojectPoint (float aX, float anY, float aZ)"
+    EOL"{"
+    EOL"  vec4 anUnprojPnt = occModelWorldMatrixInverse * occWorldViewMatrixInverse * occProjectionMatrixInverse * vec4 (aX, anY, aZ, 1.0);"
+    EOL"  return anUnprojPnt.xyz / anUnprojPnt.w;"
+    EOL"}"
+
+    EOL"void main()"
+    EOL"{"
+    EOL"  vec3 aVertex = gridPlane[gl_VertexID];"
+    EOL"  NearPoint = UnprojectPoint (aVertex.x, aVertex.y, 0.0);"
+    EOL"  FarPoint  = UnprojectPoint (aVertex.x, aVertex.y, 1.0);"
+    EOL"  MVP = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix;"
+    EOL"  gl_Position = vec4 (aVertex, 1.0);"
+    EOL"}";
+
+  TCollection_AsciiString aSrcFrag = TCollection_AsciiString()
+  + EOL"vec4 grid (vec3 theFragPos3D, vec3 theColor, float theScale, bool theIsDrawAxis, float theThickness)"
+    EOL"{"
+    EOL"  vec2 aCoord = theFragPos3D.xy * theScale;"
+
+    EOL"  vec2 aDerivative = max (fwidth (aCoord), vec2 (theThickness));"
+    EOL"  vec2 aGrid = abs (fract (aCoord - 0.5) - 0.5) / aDerivative;"
+    EOL"  float aLine = min (aGrid.x, aGrid.y);"
+    EOL"  float aMinY = min (aDerivative.y, 1.0);"
+    EOL"  float aMinX = min (aDerivative.x, 1.0);"
+
+    EOL"  vec4 aColor = vec4 (theColor, round (1.0 - min (aLine, 1.0)));"
+    EOL"  if (uIsDrawAxis && theIsDrawAxis)"
+    EOL"  {"
+    EOL"    bool isYAxis = abs(aCoord.x) < aMinX;"
+    EOL"    bool isXAxis = abs(aCoord.y) < aMinY;"
+    EOL"    if (isXAxis && isYAxis) { aColor.xyz = vec3 (0.0, 0.0, 1.0); }"
+    EOL"    else if (isXAxis) { aColor.xyz = vec3 (1.0, 0.0, 0.0); }"
+    EOL"    else if (isYAxis) { aColor.xyz = vec3 (0.0, 1.0, 0.0); }"
+    EOL"  }"
+    EOL"  return aColor;"
+    EOL" }"
+
+    EOL"float computeDepth (vec3 thePos)"
+    EOL"{"
+    EOL"  vec4 aClipSpacePos = MVP * vec4 (thePos, 1.0);"
+    EOL"  return (aClipSpacePos.z / aClipSpacePos.w);"
+    EOL"}"
+
+    EOL"float computeLinearDepth (vec3 thePos)"
+    EOL"{"
+    EOL"  float aClipSpaceDepth = computeDepth (thePos) * 2.0 - 1.0;"
+    EOL"  float aLinearDepth = (2.0 * uZNear * uZFar) / (uZFar + uZNear - aClipSpaceDepth * (uZFar - uZNear));"
+    EOL"  return aLinearDepth / uZFar;"
+    EOL"}"
+
+    EOL"void main()"
+    EOL"{"
+    EOL"  float aParam = -NearPoint.z / (FarPoint.z - NearPoint.z);"
+    EOL"  vec3 aFragPos3D = NearPoint + aParam * (FarPoint - NearPoint);"
+    EOL"  float aLinearDepth = computeLinearDepth (aFragPos3D);"
+
+    EOL"  vec4 aBigGridColor = grid (aFragPos3D, uColor, uScale, true, uThickness);"
+    EOL"  vec4 aColor = aBigGridColor.a == 0.0"
+    EOL"              ? grid (aFragPos3D, 0.25 * uColor, uScale * 10.0, false, uThickness)"
+    EOL"              : aBigGridColor;"
+    EOL"  float aDepth = computeDepth (aFragPos3D);"
+    EOL"  float aFar  = gl_DepthRange.far;"
+    EOL"  float aNear = gl_DepthRange.near;"
+    EOL"  aDepth = ((aFar - aNear) * aDepth + aNear + aFar) * 0.5;"
+    EOL"  if (aColor.a == 0.0 || (-1.0 < aLinearDepth && aLinearDepth < 0.0))"
+    EOL"  {"
+    EOL"    discard;"
+    EOL"  };"
+
+    EOL"  if (aLinearDepth < 0.0)"
+    EOL"  {"
+    EOL"    float aFading = max (0.0, 0.5 * log (abs (aLinearDepth)));"
+    EOL"    aColor.a *= aFading;"
+    EOL"  }"
+
+    EOL"  float aMaxDepth = 1.0 - 1e-5;"
+    EOL"  gl_FragDepth = uIsBackground ? aMaxDepth : min (aDepth, aMaxDepth);"
+    EOL"  occFragColor = aColor;"
+    EOL"}";
+
+  defaultGlslVersion (aProgSrc, "grid", 0);
+  aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
+  aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
+
+  return aProgSrc;
+}
index 023b574260beb6282bb7d6af2f46926afbbd4fcc..1f2df5040f3ebd8ccc19f478cb0320c386fc506d 100644 (file)
@@ -148,6 +148,9 @@ protected:
   //! Generates shader program to render correctly colored quad.
   Standard_EXPORT Handle(Graphic3d_ShaderProgram) getColoredQuadProgram() const;
 
+  //! Generates shader program to render grid.
+  Standard_EXPORT Handle(Graphic3d_ShaderProgram) getGridProgram() const;
+
   //! Prepare GLSL source for IBL generation used in PBR pipeline.
   Standard_EXPORT Handle(Graphic3d_ShaderProgram) getPBREnvBakingProgram (Standard_Integer theIndex) const;
 
index eff6bf9f3909747f91e262d960c9e6e360ed8d79..de9725674e504f028b999110c1b2f6de86dafc1e 100644 (file)
@@ -1361,6 +1361,27 @@ Standard_Boolean OpenGl_ShaderManager::preparePBREnvBakingProgram (Standard_Inte
   return Standard_True;
 }
 
+// =======================================================================
+// function : prepareGridProgram
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::prepareGridProgram()
+{
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = getGridProgram();
+
+  TCollection_AsciiString aKey;
+  if (!Create (aProgramSrc, aKey, myGridProgram))
+  {
+    myGridProgram = new OpenGl_ShaderProgram(); // just mark as invalid
+    return Standard_False;
+  }
+
+  myContext->BindProgram (myGridProgram);
+  myContext->BindProgram (Handle(OpenGl_ShaderProgram)());
+
+  return Standard_True;
+}
+
 // =======================================================================
 // function : GetBgCubeMapProgram
 // purpose  :
index f8dc9da70b343e9f38da0edc0d32e1e0d0fda089..f3f0210d960bfd491b7debf31b4e86e9a7eacda2 100644 (file)
@@ -225,6 +225,16 @@ public:
     return myContext->BindProgram (myPBREnvBakingProgram[theIndex]);
   }
 
+  //! Bind program for grid visualisation.
+  Standard_Boolean BindGridProgram()
+  {
+    if (myGridProgram.IsNull())
+    {
+      prepareGridProgram();
+    }
+    return bindProgramWithState (myGridProgram, Graphic3d_TypeOfShadingModel_Unlit);
+  }
+
   //! Generates shader program to render environment cubemap as background.
   Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram();
 
@@ -709,6 +719,9 @@ protected:
   Standard_Boolean IsPbrAllowed() const { return myShadingModel == Graphic3d_TypeOfShadingModel_Pbr
                                               || myShadingModel == Graphic3d_TypeOfShadingModel_PbrFacet; }
 
+  //! Generate standard GLSL program for grid.
+  Standard_EXPORT Standard_Boolean prepareGridProgram();
+
 protected:
 
   //! Packed properties of light source
@@ -776,6 +789,7 @@ protected:
   Handle(Graphic3d_ShaderProgram)    myBgCubeMapProgram;       //!< program for background cubemap rendering
   Handle(Graphic3d_ShaderProgram)    myBgSkydomeProgram;       //!< program for background cubemap rendering
   Handle(Graphic3d_ShaderProgram)    myColoredQuadProgram;     //!< program for correct quad rendering
+  Handle(OpenGl_ShaderProgram)       myGridProgram;            //!< program for grid rendering
 
   Handle(OpenGl_ShaderProgram)       myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
 
index 790779556779e7b528070c0260fd90a6d41729f5..6def227cf8bebf9746bdbbc59168a88f7be781c2 100644 (file)
@@ -108,6 +108,7 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myCaps           (theCaps),
   myWasRedrawnGL   (Standard_False),
   myToShowGradTrihedron  (false),
+  myToShowGrid           (false),
   myStateCounter         (theCounter),
   myCurrLightSourceState (theCounter->Increment()),
   myLightsRevision       (0),
@@ -502,6 +503,25 @@ void OpenGl_View::GraduatedTrihedronErase()
   myToShowGradTrihedron = false;
 }
 
+// =======================================================================
+// function : GridDisplay
+// purpose  :
+// =======================================================================
+void OpenGl_View::GridDisplay (const Aspect_GridParams& theGridParams)
+{
+  myGridParams = theGridParams;
+  myToShowGrid = true;
+}
+
+// =======================================================================
+// function : GridErase
+// purpose  :
+// =======================================================================
+void OpenGl_View::GridErase()
+{
+  myToShowGrid = false;
+}
+
 // =======================================================================
 // function : GraduatedTrihedronMinMaxValues
 // purpose  :
@@ -2433,8 +2453,14 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
     aContext->core11fwd->glDisable (GL_LIGHTING);
   }
 
+  // ====================================
+  //      Step 3: Redraw grid
+  // ====================================
+
+  renderGrid();
+
   // =================================
-  //      Step 3: Redraw main plane
+  //      Step 4: Redraw main plane
   // =================================
 
   // if the view is scaled normal vectors are scaled to unit
@@ -2495,7 +2521,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   myWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)());
 
   // ===============================
-  //      Step 4: Trihedron
+  //      Step 5: Trihedron
   // ===============================
 
   // Resetting GL parameters according to the default aspects
@@ -2525,6 +2551,109 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   }
 }
 
+// =======================================================================
+// function : renderGrid
+// purpose  :
+// =======================================================================
+void OpenGl_View::renderGrid()
+{
+  if (!myToShowGrid)
+  {
+    return;
+  }
+
+  const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
+  const Handle(Graphic3d_Camera)& aCamera = aContext->Camera();
+
+  Bnd_Box aBnd = MinMaxValues (Standard_True);
+  if (myGridParams.IsBackground() || aBnd.IsOut (myGridParams.Position()))
+  {
+    aBnd.Add (myGridParams.Position());
+    aCamera->ZFitAll (1.0, aBnd, aBnd);
+  }
+
+  const Standard_Real aZNear = aCamera->ZNear();
+  const Standard_Real aZFar = aCamera->ZFar();
+  const Graphic3d_Camera::Projection aProjectionType = aCamera->ProjectionType();
+
+  aCamera->SetZRange (aZNear, Max (aZNear * 1.001, aZFar));
+  if (myGridParams.IsBackground())
+  {
+    aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
+  }
+
+  aContext->ProjectionState.Push();
+  aContext->ProjectionState.SetCurrent (aCamera->ProjectionMatrixF());
+  aContext->ApplyProjectionMatrix();
+
+  const OpenGl_Mat4& aWorldViewCurrent = aContext->WorldViewState.Current();
+  OpenGl_Mat4 aWorldViewState = myGridParams.IsBackground() ? OpenGl_Mat4() : aWorldViewCurrent;
+
+  gp_Pnt aPosition = myGridParams.Position();
+  if (myGridParams.IsBackground())
+  {
+    gp_Pnt aRotationPoint = aCamera->RotationPoint();
+    Graphic3d_Vec4 aRotationVec ((float)aRotationPoint.X(), (float)aRotationPoint.Y(), (float)aRotationPoint.Z(), 1.0);
+    OpenGl_Mat4 aTranslation, aTranslationInv;
+    aTranslation.SetColumn (3, aRotationVec);
+    aTranslationInv.SetColumn (3, -aRotationVec);
+    OpenGl_Mat4 aWorldViewStateCorrected = aTranslationInv * aWorldViewCurrent * aTranslation;
+    aPosition.ChangeCoord() += gp_XYZ (aWorldViewStateCorrected (0, 3), aWorldViewStateCorrected (1, 3), -aZFar);
+
+    gp_XYZ aPanningVector (aCamera->PanningVector().X(), aCamera->PanningVector().Y(), 0.0);
+    aPosition.ChangeCoord() -= aPanningVector;
+  }
+  OpenGl_Mat4 aTranslation;
+  aTranslation.SetColumn (3, Graphic3d_Vec4 ((float)aPosition.X(), (float)aPosition.Y(), (float)aPosition.Z(), 1.0));
+
+  aContext->WorldViewState.Push();
+  aContext->WorldViewState.SetCurrent (aWorldViewState * aTranslation);
+  aContext->ApplyWorldViewMatrix();
+
+  aContext->core11fwd->glEnable (GL_DEPTH_TEST);
+  aContext->core11fwd->glDepthFunc (GL_LESS);
+  aContext->core11fwd->glDepthMask (GL_TRUE);
+  aContext->core11fwd->glEnable (GL_BLEND);
+  const bool wasDepthClamped = aContext->arbDepthClamp && aContext->core11fwd->glIsEnabled (GL_DEPTH_CLAMP);
+  if (aContext->arbDepthClamp && !wasDepthClamped)
+  {
+    aContext->core11fwd->glEnable (GL_DEPTH_CLAMP);
+  }
+
+  const Standard_Real aCameraScale = aCamera->Scale();
+  Standard_Real aScale = myGridParams.IsInfinity()
+                       ? 10.0 / pow (10.0, floor (log10 (Max (aCameraScale, 1.0))) + 1.0)
+                       : myGridParams.Scale();
+
+  if (aContext->ShaderManager()->BindGridProgram())
+  {
+    const Handle(OpenGl_ShaderProgram)& aProg = aContext->ActiveProgram();
+    aProg->SetUniform (aContext, "uZNear", GLfloat (aCamera->ZNear()));
+    aProg->SetUniform (aContext, "uZFar",  GLfloat (aCamera->ZFar()));
+    aProg->SetUniform (aContext, "uScale", GLfloat (aScale));
+    aProg->SetUniform (aContext, "uThickness", GLfloat (myGridParams.LineThickness()));
+    aProg->SetUniform (aContext, "uColor", OpenGl_Vec3 (myGridParams.Color().Rgb()));
+    aProg->SetUniform (aContext, "uIsDrawAxis", GLboolean (myGridParams.IsDrawAxis()));
+    aProg->SetUniform (aContext, "uIsBackground", GLboolean (myGridParams.IsBackground()));
+
+    aContext->core11fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+    aContext->BindProgram (NULL);
+  }
+
+  aCamera->SetZRange (aZNear, aZFar);
+  aCamera->SetProjectionType (aProjectionType);
+  aContext->core11fwd->glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  if (aContext->arbDepthClamp && !wasDepthClamped)
+  {
+    aContext->core11fwd->glDisable (GL_DEPTH_CLAMP);
+  }
+
+  aContext->WorldViewState.Pop();
+  aContext->ProjectionState.Pop();
+  aContext->ApplyWorldViewMatrix();
+  aContext->ApplyProjectionMatrix();
+}
+
 // =======================================================================
 // function : InvalidateBVHData
 // purpose  :
index 17768a06d13b2e91ac03685fbd68db8d339c1dde..023f8a4dc8f35b1dcb334150e66db057fdfe2847 100644 (file)
@@ -300,6 +300,12 @@ public: //! @name obsolete Graduated Trihedron functionality
   //! Erases Graduated Trihedron.
   Standard_EXPORT virtual void GraduatedTrihedronErase() Standard_OVERRIDE;
 
+  //! Displays Grid.
+  Standard_EXPORT virtual void GridDisplay (const Aspect_GridParams& theGridParams) Standard_OVERRIDE;
+
+  //! Erases Grid.
+  Standard_EXPORT virtual void GridErase() Standard_OVERRIDE;
+
   //! Sets minimum and maximum points of scene bounding box for Graduated Trihedron stored in graphic view object.
   //! @param theMin [in] the minimum point of scene.
   //! @param theMax [in] the maximum point of scene.
@@ -390,6 +396,9 @@ protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
                                               OpenGl_FrameBuffer*    theOitAccumFbo,
                                               const Standard_Boolean theToDrawImmediate);
 
+  //! Renders grid
+  Standard_EXPORT void renderGrid();
+
   //! Renders trihedron.
   void renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace);
 
@@ -443,7 +452,9 @@ protected:
   gp_XYZ                          myLocalOrigin;
   Handle(OpenGl_FrameBuffer)      myFBO;
   Standard_Boolean                myToShowGradTrihedron;
+  Standard_Boolean                myToShowGrid;
   Graphic3d_GraduatedTrihedron    myGTrihedronData;
+  Aspect_GridParams               myGridParams;
 
   Handle(Graphic3d_LightSet)      myNoShadingLight;
   Handle(Graphic3d_LightSet)      myLights;
index ca4a7c911d2cc9b91047a4cb18df6505e2487550..a812fd9896179da829dba484636ea0e8fb077062 100644 (file)
@@ -106,6 +106,11 @@ void V3d_CircularGrid::Display ()
   UpdateDisplay();
 }
 
+void V3d_CircularGrid::Update()
+{
+  //
+}
+
 void V3d_CircularGrid::Erase () const
 {
   myStructure->Erase ();
index f7278ef9c828bbd3923100a84543bb190da9580a..674ad7e2ff147b565793a0054022bf6c59d4c160 100644 (file)
@@ -38,15 +38,17 @@ public:
   Standard_EXPORT virtual ~V3d_CircularGrid();
 
   Standard_EXPORT void SetColors (const Quantity_Color& aColor, const Quantity_Color& aTenthColor) Standard_OVERRIDE;
-  
+
   Standard_EXPORT void Display() Standard_OVERRIDE;
-  
+
+  Standard_EXPORT void Update() Standard_OVERRIDE;
+
   Standard_EXPORT void Erase() const Standard_OVERRIDE;
-  
+
   Standard_EXPORT Standard_Boolean IsDisplayed() const Standard_OVERRIDE;
-  
+
   Standard_EXPORT void GraphicValues (Standard_Real& Radius, Standard_Real& OffSet) const;
-  
+
   Standard_EXPORT void SetGraphicValues (const Standard_Real Radius, const Standard_Real OffSet);
   
   //! Dumps the content of me into the stream
index 35b1d2b2579e7e701ed67c559333849c2b4b14c2..fb13f15d88c3f07cb455145e5a7681ed78fe456c 100644 (file)
@@ -106,6 +106,12 @@ void V3d_RectangularGrid::Display ()
   UpdateDisplay();
 }
 
+void V3d_RectangularGrid::Update()
+{
+  SetXStep (XStep() + 1);
+  UpdateDisplay();
+}
+
 void V3d_RectangularGrid::Erase () const
 {
   myStructure->Erase ();
index e8ea5241e78813c09353329cb3aaa48ee741b628..35e5922c39356af1f8031211dfdb59d530348995 100644 (file)
@@ -40,6 +40,8 @@ public:
   
   Standard_EXPORT virtual void Display() Standard_OVERRIDE;
   
+  Standard_EXPORT virtual void Update() Standard_OVERRIDE;
+
   Standard_EXPORT virtual void Erase() const Standard_OVERRIDE;
   
   Standard_EXPORT virtual Standard_Boolean IsDisplayed() const Standard_OVERRIDE;
index 7658ea79842fcff2bbafee0c277ebbb36d22cf72..569299d4772bcc13ce9b203698866639d01612ef 100644 (file)
@@ -3779,6 +3779,24 @@ void V3d_View::GraduatedTrihedronErase()
   myView->GraduatedTrihedronErase();
 }
 
+//=============================================================================
+//function : GridDisplay
+//purpose  :
+//=============================================================================
+void V3d_View::GridDisplay (const Aspect_GridParams& theGridParams)
+{
+  myView->GridDisplay (theGridParams);
+}
+
+//=============================================================================
+//function : GridErase
+//purpose  :
+//=============================================================================
+void V3d_View::GridErase()
+{
+  myView->GridErase();
+}
+
 // =======================================================================
 // function : DumpJson
 // purpose  :
index 22847902e993e4815eb548aa5bd8ae78b1f58868..4b996e437426a9f75afa5d27144baad8246c8648 100644 (file)
@@ -318,6 +318,12 @@ public:
   //! Erases a graduated trihedron from the view.
   Standard_EXPORT void GraduatedTrihedronErase();
 
+  //! Displays a grid.
+  Standard_EXPORT void GridDisplay (const Aspect_GridParams& theGridParams);
+
+  //! Erases a grid from the view.
+  Standard_EXPORT void GridErase();
+
   //! modify the Projection of the view perpendicularly to
   //! the privileged plane of the viewer.
   Standard_EXPORT void SetFront();
index d700adce803dae7ba38b9e8d77a0db929e36e944..6b591d218c0847d6d88cb8c4a7b453cfef07a3f1 100644 (file)
@@ -5392,6 +5392,116 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
   return 0;
 }
 
+//==============================================================================
+//function : VInfGrid
+//purpose  :
+//==============================================================================
+static int VInfGrid (Draw_Interpretor& /*theDI*/,
+                     Standard_Integer  theArgNb,
+                     const char**      theArgVec)
+{
+  Handle(V3d_View)   aView = ViewerTest::CurrentView();
+  Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
+  if (aView.IsNull() || aViewer.IsNull())
+  {
+    Message::SendFail("Error: no active viewer");
+    return 1;
+  }
+
+  Aspect_GridParams aGridParams;
+  Standard_Boolean toDisplay = true;
+  ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.LowerCase();
+    if (anUpdateTool.parseRedrawMode(theArgVec[anArgIter]))
+    {
+      continue;
+    }
+    else if (anArgIter < theArgNb && anArg == "-background")
+    {
+      aGridParams.SetIsBackground (Standard_True);
+    }
+    else if (anArgIter + 1 < theArgNb && anArg == "-drawaxis")
+    {
+      Standard_Integer aVal = Draw::Atoi (theArgVec[++anArgIter]);
+      if (aVal == 0)
+      {
+        aGridParams.SetIsDrawAxis (Standard_False);
+      }
+      else if (aVal == 1)
+      {
+        aGridParams.SetIsDrawAxis (Standard_True);
+      }
+      else
+      {
+        Message::SendFail() << "Syntax error at '" << anArg << " " << aVal <<"'";
+        return 1;
+      }
+    }
+    else if (anArgIter + 3 < theArgNb && (anArg == "-color"))
+    {
+      Quantity_Color aColor;
+      aColor.SetValues (Draw::Atof (theArgVec[anArgIter + 1]), Draw::Atof (theArgVec[anArgIter + 2]), Draw::Atof (theArgVec[anArgIter + 3]), Quantity_TOC_RGB);
+      aGridParams.SetColor (aColor);
+      anArgIter += 3;
+    }
+    else if (anArgIter + 3 < theArgNb && anArg == "-origin")
+    {
+      gp_Pnt aPoint;
+      aPoint.SetXYZ (gp_XYZ (Draw::Atof (theArgVec[anArgIter + 1]), Draw::Atof (theArgVec[anArgIter + 2]), Draw::Atof (theArgVec[anArgIter + 3])));
+      aGridParams.SetPosition (aPoint);
+      anArgIter += 3;
+    }
+    else if (anArgIter + 1 < theArgNb && (anArg == "-inf"))
+    {
+      Standard_Integer aVal = Draw::Atoi(theArgVec[++anArgIter]);
+      if (aVal == 0)
+      {
+        aGridParams.SetIsInfinity (Standard_False);
+      }
+      else if (aVal == 1)
+      {
+        aGridParams.SetIsInfinity (Standard_True);
+      }
+      else
+      {
+        Message::SendFail() << "Syntax error at '" << anArg << " " << aVal << "'";
+        return 1;
+      }
+    }
+    else if (anArgIter + 1 < theArgNb && (anArg == "-scale"))
+    {
+      aGridParams.SetScale (Draw::Atof(theArgVec[++anArgIter]));
+    }
+    else if (anArgIter + 1 < theArgNb && anArg == "-linethickness")
+    {
+      aGridParams.SetLineThickness (Draw::Atof (theArgVec[++anArgIter]));
+    }
+    else if (anArgIter >= theArgNb && anArg == "off")
+    {
+      toDisplay = Standard_False;
+    }
+    else
+    {
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
+      return 1;
+    }
+  }
+
+  if (toDisplay)
+  {
+    ViewerTest::CurrentView()->GridDisplay (aGridParams);
+  }
+  else
+  {
+    ViewerTest::CurrentView()->GridErase();
+  }
+
+  return 0;
+}
+
 //==============================================================================
 //function : VPriviledgedPlane
 //purpose  :
@@ -14352,6 +14462,11 @@ vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle An
       [-step StepRadius NbDivisions] [-radius Radius]
 )" /* [vgrid] */);
 
+  addCmd("vinfgrid", VInfGrid, /* [vinfgrid] */ R"(
+vinfgrid [off] [-background] [-drawAxis {0|1}] [-color R G B] [-origin X Y Z] 
+      [-inf {0|1}] [-scale value] [-lineThickness value]
+)" /* [vinfgrid] */);
+
   addCmd ("vpriviledgedplane", VPriviledgedPlane, /* [vpriviledgedplane] */ R"(
 vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]
 Sets or prints viewer's priviledged plane geometry:
diff --git a/tests/v3d/grid/ortho b/tests/v3d/grid/ortho
new file mode 100644 (file)
index 0000000..58bae04
--- /dev/null
@@ -0,0 +1,23 @@
+puts "=================================="
+puts "Grid in ortographic projection"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vaxo
+
+box b 1 2 3
+vdisplay b -dispMode 1
+
+vcamera -ortho
+
+vfit
+vzoom 0.1
+
+vinfgrid
+vdump $imagedir/${casename}_0.png
+
+vinfgrid -background -drawAxis 0 -color 0 0 1 -origin 1 1 1 -inf 1 -lineThickness 0.05
+vdump $imagedir/${casename}_1.png
diff --git a/tests/v3d/grid/persp b/tests/v3d/grid/persp
new file mode 100644 (file)
index 0000000..0eb24ad
--- /dev/null
@@ -0,0 +1,23 @@
+puts "=================================="
+puts "Grid in perspective projection"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vaxo
+
+box b 1 2 3
+vdisplay b -dispMode 1
+
+vcamera -persp
+
+vfit
+vzoom 0.1
+
+vinfgrid
+vdump $imagedir/${casename}_0.png
+
+vinfgrid -background -drawAxis 0 -color 0 0 1 -origin 1 1 1 -inf 1 -lineThickness 0.05
+vdump $imagedir/${casename}_1.png