]> OCCT Git - occt.git/commitdiff
0032752: Visualization, TKOpenGl - extend V3d_View::ToPixMap() options with Z-layer CR0-IR-2024-05-17 IR-2024-05-17
authordrochalo <diogo.lopes@opencascade.com>
Fri, 3 Nov 2023 10:48:11 +0000 (10:48 +0000)
committerdpasukhi <dpasukhi@opencascade.com>
Sun, 19 May 2024 15:03:09 +0000 (16:03 +0100)
Added option to dump only a selection of zlayer's content.
Changed zlayers redraw and render method for selection of layers to render.
Added filters for layer parsing.
Modified vdump command.
Added test with multiple dumps for comparison.
Added option to dump shadow maps.

14 files changed:
src/Graphic3d/Graphic3d_BufferType.hxx
src/Graphic3d/Graphic3d_CView.cxx
src/Graphic3d/Graphic3d_CView.hxx
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_LayerFilter.hxx
src/OpenGl/OpenGl_LayerList.cxx
src/OpenGl/OpenGl_LayerList.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/V3d/V3d_ImageDumpOptions.hxx
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/ViewerTest/ViewerTest.cxx
tests/v3d/bugs/bug32752 [new file with mode: 0644]

index 99e449bca27d40e298676f70b95a4e73ed887aa9..3e7e9f2a362889d80e2595da51887ff401844f18 100644 (file)
 //! Define buffers available for dump
 enum Graphic3d_BufferType
 {
-  Graphic3d_BT_RGB,   //!< color buffer without alpha component
-  Graphic3d_BT_RGBA,  //!< color buffer
-  Graphic3d_BT_Depth, //!< depth buffer
+  Graphic3d_BT_RGB,                 //!< color buffer without alpha component
+  Graphic3d_BT_RGBA,                //!< color buffer
+  Graphic3d_BT_Depth,               //!< depth buffer
   Graphic3d_BT_RGB_RayTraceHdrLeft, //!< left view HDR color buffer for Ray-Tracing
-  Graphic3d_BT_Red,   //!< color buffer, red channel
+  Graphic3d_BT_Red,                 //!< color buffer, red channel
+  Graphic3d_BT_ShadowMap,           //!< buffer with shadow map
 };
 
 #endif // _Graphic3d_BufferType_H__
index 59e0ee75a9f373e8d5ee4a256f20ed4629e3609f..2a0be6b193304cf6175720d90df1f2c2c64f5eab 100644 (file)
@@ -42,6 +42,9 @@ Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theM
   myBackfacing (Graphic3d_TypeOfBackfacingModel_Auto),
   myVisualization (Graphic3d_TOV_WIREFRAME),
   //
+  myZLayerTarget (Graphic3d_ZLayerId_BotOSD),
+  myZLayerRedrawMode (Standard_False),
+  //
   myBgColor (Quantity_NOC_BLACK),
   myBackgroundType (Graphic3d_TOB_NONE),
   myToUpdateSkydome (Standard_False),
index 5fe56d44677ac8313f6229f37303f7bdd88ff520..abebcebc61c1704205ad460cbd2f6dbe8f0eac30 100644 (file)
@@ -112,6 +112,18 @@ public:
   //! Sets visualization type of the view.
   void SetVisualizationType (const Graphic3d_TypeOfVisualization theType) { myVisualization = theType; }
 
+  //! Returns ZLayerId target
+  Graphic3d_ZLayerId ZLayerTarget() const { return myZLayerTarget; }
+
+  //! Sets ZLayerId target.
+  void SetZLayerTarget (const Graphic3d_ZLayerId theTarget) { myZLayerTarget = theTarget; }
+
+  //! Returns ZLayerId redraw mode
+  Standard_Boolean ZLayerRedrawMode() const { return myZLayerRedrawMode; }
+
+  //! Sets ZLayerId redraw mode.
+  void SetZLayerRedrawMode (const Standard_Boolean theMode) { myZLayerRedrawMode = theMode; }
+
   //! Switches computed HLR mode in the view
   Standard_EXPORT void SetComputedMode (const Standard_Boolean theMode);
 
@@ -258,6 +270,11 @@ public:
   //! Dump active rendering buffer into specified memory buffer.
   virtual Standard_Boolean BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType) = 0;
 
+  //! Dumps the graphical contents of a shadowmap framebuffer into an image.
+  //! @param theImage the image to store the shadow map.
+  //! @param theLightName [in] name of the light used to generate the shadow map.
+  virtual Standard_Boolean ShadowMapDump (Image_PixMap& theImage, const TCollection_AsciiString& theLightName) = 0;
+
   //! Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated.
   virtual void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) = 0;
 
@@ -638,15 +655,18 @@ protected:
   Graphic3d_Vec2d               mySubviewOffset;            //!< subview corner offset within parent view
 
   Handle(Graphic3d_StructureManager) myStructureManager;
-  Handle(Graphic3d_Camera)  myCamera;
-  Graphic3d_SequenceOfStructure myStructsToCompute;
-  Graphic3d_SequenceOfStructure myStructsComputed;
-  Graphic3d_MapOfStructure myStructsDisplayed;
-  Standard_Boolean myIsInComputedMode;
-  Standard_Boolean myIsActive;
-  Standard_Boolean myIsRemoved;
-  Graphic3d_TypeOfBackfacingModel myBackfacing;
-  Graphic3d_TypeOfVisualization myVisualization;
+  Handle(Graphic3d_Camera)           myCamera;
+  Graphic3d_SequenceOfStructure      myStructsToCompute;
+  Graphic3d_SequenceOfStructure      myStructsComputed;
+  Graphic3d_MapOfStructure           myStructsDisplayed;
+  Standard_Boolean                   myIsInComputedMode;
+  Standard_Boolean                   myIsActive;
+  Standard_Boolean                   myIsRemoved;
+  Graphic3d_TypeOfBackfacingModel    myBackfacing;
+  Graphic3d_TypeOfVisualization      myVisualization;
+
+  Graphic3d_ZLayerId      myZLayerTarget;      //!< ZLayerId for redrawing the content of specific zlayers.
+  Standard_Boolean        myZLayerRedrawMode;  //!< If true redraws single layer, otherwise redraws group of layers.
 
   Quantity_ColorRGBA           myBgColor;
   Handle(Graphic3d_TextureMap) myBackgroundImage;
index ca4ac757e2dd1474929a21746defcb0618b108f4..0fdbe4ce81c1af5a1d78f14e838db616ee342d0d 100644 (file)
@@ -978,7 +978,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
         return false;
       }
 
-      aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED;
+      aFormat = theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap ? GL_DEPTH_COMPONENT : GL_RED;
       aType   = GL_UNSIGNED_BYTE;
       break;
     }
@@ -989,7 +989,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
         return false;
       }
 
-      aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED;
+      aFormat = theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap ? GL_DEPTH_COMPONENT : GL_RED;
       aType   = GL_UNSIGNED_SHORT;
       break;
     }
@@ -1000,7 +1000,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
         return false;
       }
 
-      aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED;
+      aFormat = theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap ? GL_DEPTH_COMPONENT : GL_RED;
       aType   = GL_FLOAT;
       break;
     }
@@ -1113,7 +1113,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
 
   GLint aReadBufferPrev = GL_BACK;
   if (theGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES
-   && theBufferType == Graphic3d_BT_Depth
+   && (theBufferType == Graphic3d_BT_Depth || theBufferType == Graphic3d_BT_ShadowMap)
    && aFormat != GL_DEPTH_COMPONENT)
   {
     return Standard_False;
index 0531bf1b5620a0b869ce0e252eaf80f53d9a07a1..5483f0f3d2a2effba80e5d28dcf843d000aa017a 100644 (file)
@@ -23,6 +23,7 @@ enum OpenGl_LayerFilter
   OpenGl_LF_All,        //!< process all layers
   OpenGl_LF_Upper,      //!< process only top non-raytracable layers
   OpenGl_LF_Bottom,     //!< process only Graphic3d_ZLayerId_BotOSD
+  OpenGl_LF_Single,     //!< process single layer
   OpenGl_LF_RayTracable //!< process only normal raytracable layers (save the bottom layer)
 };
 
index 52a494d0e2bc200e36a87f0a6218651cc11784f3..4cceccfdb5ebd56b180e1f57fd9d06e71e628eae 100644 (file)
@@ -58,10 +58,12 @@ namespace
     //! Main constructor.
     OpenGl_FilteredIndexedLayerIterator (const NCollection_List<Handle(Graphic3d_Layer)>& theSeq,
                                          Standard_Boolean theToDrawImmediate,
-                                         OpenGl_LayerFilter theLayersToProcess)
+                                         OpenGl_LayerFilter theFilterMode,
+                                         Graphic3d_ZLayerId theLayersToProcess)
     : myIter (theSeq),
-      myLayersToProcess (theLayersToProcess),
-      myToDrawImmediate (theToDrawImmediate)
+      myFilterMode (theFilterMode),
+      myToDrawImmediate (theToDrawImmediate),
+      myLayersToProcess (theLayersToProcess)
     {
       next();
     }
@@ -94,11 +96,15 @@ namespace
           continue;
         }
 
-        switch (myLayersToProcess)
+        switch (myFilterMode)
         {
           case OpenGl_LF_All:
           {
-            return;
+            if (aLayer->LayerId() >= myLayersToProcess)
+            {
+              return;
+            }
+            break;
           }
           case OpenGl_LF_Upper:
           {
@@ -119,6 +125,14 @@ namespace
             }
             break;
           }
+          case OpenGl_LF_Single:
+          {
+            if (aLayer->LayerId() == myLayersToProcess)
+            {
+              return;
+            }
+            break;
+          }
           case OpenGl_LF_RayTracable:
           {
             if (aLayer->LayerSettings().IsRaytracable()
@@ -133,8 +147,9 @@ namespace
     }
   private:
     OpenGl_IndexedLayerIterator myIter;
-    OpenGl_LayerFilter          myLayersToProcess;
+    OpenGl_LayerFilter          myFilterMode;
     Standard_Boolean            myToDrawImmediate;
+    Graphic3d_ZLayerId          myLayersToProcess;
   };
 
   static const Standard_Integer THE_DRAW_BUFFERS0[]   = { GL_COLOR_ATTACHMENT0 };
@@ -714,7 +729,8 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace
 //=======================================================================
 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
                                const Standard_Boolean          theToDrawImmediate,
-                               const OpenGl_LayerFilter        theLayersToProcess,
+                               const OpenGl_LayerFilter        theFilterMode,
+                               const Graphic3d_ZLayerId        theLayersToProcess,
                                OpenGl_FrameBuffer*             theReadDrawFbo,
                                OpenGl_FrameBuffer*             theOitAccumFbo) const
 {
@@ -750,7 +766,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
                                   && !isShadowMapPass;
   const Handle(Graphic3d_LightSet)    aLightsBack = aCtx->ShaderManager()->LightSourceState().LightSources();
   const Handle(OpenGl_ShadowMapArray) aShadowMaps = aCtx->ShaderManager()->LightSourceState().ShadowMaps();
-  for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();)
+  for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, theToDrawImmediate, theFilterMode, theLayersToProcess); aLayerIterStart.More();)
   {
     bool hasSkippedDepthLayers = false;
     for (int aPassIter = toPerformDepthPrepass ? 0 : 2; aPassIter < 3; ++aPassIter)
index 442364334dd1c2b9ac5cd2fcc8041473cba1c1e6..eb614f55afd9e2b7ead75703ad730a7d4307d877 100644 (file)
@@ -102,7 +102,8 @@ public:
   //! Render this element
   Standard_EXPORT void Render (const Handle(OpenGl_Workspace)& theWorkspace,
                                const Standard_Boolean          theToDrawImmediate,
-                               const OpenGl_LayerFilter        theLayersToProcess,
+                               const OpenGl_LayerFilter        theFilterMode,
+                               const Graphic3d_ZLayerId        theLayersToProcess,
                                OpenGl_FrameBuffer*             theReadDrawFbo,
                                OpenGl_FrameBuffer*             theOitAccumFbo) const;
 
index 790779556779e7b528070c0260fd90a6d41729f5..e1010f47df377274ce6b595d27c4535e857ed948 100644 (file)
@@ -520,12 +520,12 @@ Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3
   const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
   if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft)
   {
-    return myWorkspace->BufferDump(myFBO, theImage, theBufferType);
+    return myWorkspace->BufferDump (myFBO, theImage, theBufferType);
   }
 
   if (!myRaytraceParameters.AdaptiveScreenSampling)
   {
-    return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
+    return myWorkspace->BufferDump (myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
   }
 
   if (aCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES)
@@ -572,6 +572,71 @@ Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3
   return true;
 }
 
+//=======================================================================
+//function : ShadowMapDump
+//purpose  :
+//=======================================================================
+Standard_Boolean OpenGl_View::ShadowMapDump (Image_PixMap& theImage, const TCollection_AsciiString& theLightName)
+{
+  if (!myShadowMaps->IsValid())
+  {
+    return Standard_False;
+  }
+
+  const Handle(OpenGl_Context)& aGlCtx = myWorkspace->GetGlContext();
+  for (Standard_Integer aShadowIter = 0; aShadowIter < myShadowMaps->Size(); ++aShadowIter)
+  {
+    Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue(aShadowIter);
+    if (!aShadow.IsNull() && aShadow->LightSource()->Name() == theLightName)
+    {
+      const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer();
+      if (aShadowFbo->GetVPSizeX() == myRenderParams.ShadowMapResolution)
+      {
+        if ((Standard_Integer)theImage.Width() != aShadowFbo->GetVPSizeX() || (Standard_Integer)theImage.Height() != aShadowFbo->GetVPSizeY())
+        {
+          theImage.InitZero(Image_Format_GrayF, aShadowFbo->GetVPSizeX(), aShadowFbo->GetVPSizeY());
+        }
+        GLint aReadBufferPrev = GL_BACK;
+        // Bind FBO if used.
+        if (!aShadowFbo.IsNull() && aShadowFbo->IsValid())
+        {
+          aShadowFbo->BindBuffer (aGlCtx);
+        }
+        else if (aGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES)
+        {
+          aGlCtx->core11fwd->glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
+          GLint aDrawBufferPrev = GL_BACK;
+          aGlCtx->core11fwd->glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
+          aGlCtx->core11fwd->glReadBuffer (aDrawBufferPrev);
+        }
+        // Setup alignment.
+        const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL.
+        aGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
+        // Read data.
+        aGlCtx->core11fwd->glReadPixels (0, 0, GLsizei(theImage.SizeX()), GLsizei(theImage.SizeY()), GL_DEPTH_COMPONENT, GL_FLOAT, theImage.ChangeData());
+        aGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1);
+        if (aGlCtx->hasPackRowLength)
+        {
+          aGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0);
+        }
+        // Unbind FBO.
+        if (!aShadowFbo.IsNull() && aShadowFbo->IsValid())
+        {
+          aShadowFbo->UnbindBuffer (aGlCtx);
+        }
+        else if (aGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES)
+        {
+          aGlCtx->core11fwd->glReadBuffer (aReadBufferPrev);
+        }
+        // Check for errors.
+        const bool hasErrors = aGlCtx->ResetErrors (true);
+        return !hasErrors;
+      }
+    }
+  }
+  return Standard_False;
+}
+
 // =======================================================================
 // function : GradientBackground
 // purpose  :
@@ -2583,7 +2648,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
       if (aCtx->arbFBOBlit != NULL)
       {
         // Render bottom OSD layer
-        myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, theReadDrawFbo, theOitAccumFbo);
+        myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, myZLayerTarget, theReadDrawFbo, theOitAccumFbo);
 
         const Standard_Integer aPrevFilter = myWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_NonRaytraceableOnly);
         myWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_NonRaytraceableOnly);
@@ -2599,7 +2664,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
           }
 
           // Render non-polygonal elements in default layer
-          myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_RayTracable, theReadDrawFbo, theOitAccumFbo);
+          myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_RayTracable, myZLayerTarget, theReadDrawFbo, theOitAccumFbo);
         }
         myWorkspace->SetRenderFilter (aPrevFilter);
       }
@@ -2622,7 +2687,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
       raytrace (aSizeXY.x(), aSizeXY.y(), theProjection, theReadDrawFbo, aCtx);
 
       // Render upper (top and topmost) OpenGL layers
-      myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper, theReadDrawFbo, theOitAccumFbo);
+      myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper, myZLayerTarget, theReadDrawFbo, theOitAccumFbo);
     }
   }
 
@@ -2630,7 +2695,9 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
   // mode or in case of ray-tracing failure
   if (toRenderGL)
   {
-    myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_All, theReadDrawFbo, theOitAccumFbo);
+    // check if only a single layer is to be dumped
+    OpenGl_LayerFilter aFilter = myZLayerRedrawMode ? OpenGl_LF_Single : OpenGl_LF_All;
+    myZLayers.Render (myWorkspace, theToDrawImmediate, aFilter, myZLayerTarget, theReadDrawFbo, theOitAccumFbo);
 
     // Set flag that scene was redrawn by standard pipeline
     myWasRedrawnGL = Standard_True;
index 17768a06d13b2e91ac03685fbd68db8d339c1dde..5d4cca1029ec79d4146c49d5e94bb0c796d02a33 100644 (file)
@@ -111,6 +111,12 @@ public:
   Standard_EXPORT virtual Standard_Boolean BufferDump (Image_PixMap& theImage,
                                                        const Graphic3d_BufferType& theBufferType) Standard_OVERRIDE;
 
+  //! Dumps the graphical contents of a shadowmap framebuffer into an image.
+  //! @param theImage the image to store the shadow map.
+  //! @param theLightName [in] name of the light used to generate the shadow map.
+  Standard_EXPORT virtual Standard_Boolean ShadowMapDump (Image_PixMap& theImage,
+                                                             const TCollection_AsciiString& theLightName) Standard_OVERRIDE;
+
   //! Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated.
   Standard_EXPORT virtual void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) Standard_OVERRIDE;
 
index 368f7c881d639b2e96bb23f7951c1af83f5b58bf..a15f57b83acbc1e5fd4e81cfaf7d62de241677be 100644 (file)
 
 #include <Graphic3d_BufferType.hxx>
 #include <V3d_StereoDumpOptions.hxx>
+#include <Graphic3d_ZLayerId.hxx>
 
 //! The structure defines options for image dump functionality.
 struct V3d_ImageDumpOptions
 {
 
-  Standard_Integer      Width;          //!< width  of image dump to allocate an image, 0 by default (meaning that image should be already allocated)
-  Standard_Integer      Height;         //!< height of image dump to allocate an image, 0 by default (meaning that image should be already allocated)
-  Graphic3d_BufferType  BufferType;     //!< which buffer to dump (color / depth), Graphic3d_BT_RGB by default
-  V3d_StereoDumpOptions StereoOptions;  //!< dumping stereoscopic camera, V3d_SDO_MONO by default (middle-point monographic projection)
-  Standard_Integer      TileSize;       //!< the view dimension limited for tiled dump, 0 by default (automatic tiling depending on hardware capabilities)
-  Standard_Boolean      ToAdjustAspect; //!< flag to override active view aspect ratio by (Width / Height) defined for image dump (TRUE by default)
+  Standard_Integer      Width;          //!< Width  of image dump to allocate an image, 0 by default (meaning that image should be already allocated).
+  Standard_Integer      Height;         //!< Height of image dump to allocate an image, 0 by default (meaning that image should be already allocated).
+  Graphic3d_BufferType  BufferType;     //!< Which buffer to dump (color / depth), Graphic3d_BT_RGB by default.
+  V3d_StereoDumpOptions StereoOptions;  //!< Dumping stereoscopic camera, V3d_SDO_MONO by default (middle-point monographic projection).
+  Standard_Integer      TileSize;       //!< The view dimension limited for tiled dump, 0 by default (automatic tiling depending on hardware capabilities).
+  Standard_Boolean      ToAdjustAspect; //!< Flag to override active view aspect ratio by (Width / Height) defined for image dump (TRUE by default).
+  Graphic3d_ZLayerId    TargetZLayerId; //!< Target z layer id which defines the last layer to be drawn before image dump.
+  Standard_Boolean      IsSingleLayer;  //<! Flags if dumping is to be done to a single or to multiple layers.
+  Standard_CString      LightName;      //<! Name of the target light whose shadowmap is to be dumped.
 
 public:
 
   //! Default constructor.
   V3d_ImageDumpOptions()
-  : Width         (0),
-    Height        (0),
-    BufferType    (Graphic3d_BT_RGB),
-    StereoOptions (V3d_SDO_MONO),
-    TileSize      (0),
-    ToAdjustAspect(Standard_True) {}
-
+  : Width          (0),
+    Height         (0),
+    BufferType     (Graphic3d_BT_RGB),
+    StereoOptions  (V3d_SDO_MONO),
+    TileSize       (0),
+    ToAdjustAspect (Standard_True),
+    TargetZLayerId (Graphic3d_ZLayerId_BotOSD),
+    IsSingleLayer  (Standard_False),
+    LightName      ("") {}
+    
 };
 
 #endif // _V3d_ImageDumpOptions_HeaderFile
index 7658ea79842fcff2bbafee0c277ebbb36d22cf72..adafb827f41562a500d8e41392faae615a0fdb0e 100644 (file)
@@ -2814,6 +2814,7 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
         case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
         case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
         case Graphic3d_BT_Red:                 aFormat = Image_Format_Gray;  break;
+        case Graphic3d_BT_ShadowMap:           aFormat = Image_Format_GrayF; break;
       }
 
       if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
@@ -2940,7 +2941,9 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
   {
     aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
   }
-
+  //apply zlayer rendering parameters to view
+  myView->SetZLayerTarget (theParams.TargetZLayerId);
+  myView->SetZLayerRedrawMode (theParams.IsSingleLayer);
   // render immediate structures into back buffer rather than front
   const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
 
@@ -2952,7 +2955,19 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
       myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
     }
     Redraw();
-    isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
+    if (theParams.BufferType == Graphic3d_BT_ShadowMap)
+    {
+      // draw shadow maps
+      if (!myView->ShadowMapDump (theImage, theParams.LightName))
+      {
+        Message::SendFail ("OpenGl_View::BufferDump() failed to dump shadowmap");
+        isSuccess = Standard_False;
+      }
+    }
+    else 
+    {
+      isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
+    }
   }
   else
   {
@@ -3024,6 +3039,9 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
     myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
   }
   myView->SetFBO (aPrevFBOPtr);
+  //apply default zlayer rendering parameters to view
+  myView->SetZLayerTarget (Graphic3d_ZLayerId_BotOSD);
+  myView->SetZLayerRedrawMode (Standard_False);
   return isSuccess;
 }
 
index 22847902e993e4815eb548aa5bd8ae78b1f58868..93804995a4b8632ba59c575d50acd268ea751a9b 100644 (file)
@@ -851,19 +851,25 @@ public:
   //! @param theBufferType     type of the view buffer to dump (color / depth)
   //! @param theToAdjustAspect when true, active view aspect ratio will be overridden by (theWidth / theHeight)
   //! @param theStereoOptions  how to dump stereographic camera
-  Standard_Boolean ToPixMap (Image_PixMap& theImage,
-                             const Standard_Integer theWidth,
-                             const Standard_Integer theHeight,
+  Standard_Boolean ToPixMap (Image_PixMap&               theImage,
+                             const Standard_Integer      theWidth,
+                             const Standard_Integer      theHeight,
                              const Graphic3d_BufferType& theBufferType     = Graphic3d_BT_RGB,
                              const Standard_Boolean      theToAdjustAspect = Standard_True,
-                             const V3d_StereoDumpOptions theStereoOptions  = V3d_SDO_MONO)
+                             const Graphic3d_ZLayerId    theTargetZLayerId = Graphic3d_ZLayerId_BotOSD,
+                             const Standard_Integer      theIsSingleLayer  = Standard_False,
+                             const V3d_StereoDumpOptions theStereoOptions  = V3d_SDO_MONO,
+                             const Standard_CString      theLightName = "")
   {
     V3d_ImageDumpOptions aParams;
-    aParams.Width  = theWidth;
-    aParams.Height = theHeight;
-    aParams.BufferType = theBufferType;
+    aParams.Width          = theWidth;
+    aParams.Height         = theHeight;
+    aParams.BufferType     = theBufferType;
     aParams.StereoOptions  = theStereoOptions;
     aParams.ToAdjustAspect = theToAdjustAspect;
+    aParams.TargetZLayerId = theTargetZLayerId;
+    aParams.IsSingleLayer  = theIsSingleLayer;
+    aParams.LightName      = theLightName;
     return ToPixMap (theImage, aParams);
   }
 
index dced0cf3f938d2e4762f64556239f46f0319c906..380f5ac67bd58ab005a0c64beb7e2a2170d5b8dc 100644 (file)
@@ -966,8 +966,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
   V3d_ImageDumpOptions  aParams;
   Handle(Graphic3d_Camera) aCustomCam;
-  aParams.BufferType    = Graphic3d_BT_RGB;
-  aParams.StereoOptions = V3d_SDO_MONO;
+  aParams.BufferType     = Graphic3d_BT_RGB;
+  aParams.StereoOptions  = V3d_SDO_MONO;
+  aParams.TargetZLayerId = Graphic3d_ZLayerId_BotOSD;
+  aParams.IsSingleLayer  = Standard_False;
+  aParams.LightName      = "";
   for (; anArgIter < theArgNb; ++anArgIter)
   {
     TCollection_AsciiString anArg (theArgVec[anArgIter]);
@@ -998,6 +1001,31 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
       {
         aParams.BufferType = Graphic3d_BT_Depth;
       }
+      else if (aBufArg == "shadowmap")
+      {
+        if (++anArgIter >= theArgNb)
+        {
+          Message::SendFail() << "Error: missing light name for shadowmap dump";
+          return 1;
+        }
+        aParams.BufferType = Graphic3d_BT_ShadowMap;
+        aParams.LightName = theArgVec[anArgIter];
+        Standard_Boolean isLightFound = Standard_False;
+        for (V3d_ListOfLightIterator aLightIter(aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next())
+        {
+          Handle(V3d_Light) aLight = aLightIter.Value();
+          if (aLight->Name() == aParams.LightName)
+          {
+            isLightFound = Standard_True;
+            break;
+          }
+        }
+        if (!isLightFound)
+        {
+          Message::SendFail() << "Error: couldn't find light '" << aParams.LightName << "'";
+          return 1;
+        }
+      }
       else
       {
         Message::SendFail() << "Error: unknown buffer '" << aBufArg << "'";
@@ -1105,6 +1133,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
     {
       aParams.BufferType = Graphic3d_BT_Depth;
     }
+    else if (anArg == "-shadowmap"
+          || anArg == "shadowmap")
+    {
+      aParams.BufferType = Graphic3d_BT_ShadowMap;
+    }
     else if (anArg == "-width"
           || anArg ==  "width"
           || anArg ==  "sizex")
@@ -1147,6 +1180,39 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
       }
       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
     }
+    else if (anArg == "-grouplayer")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        Message::SendFail() << "Error: integer value is expected right after 'grouplayer'";
+        return 1;
+      }
+      Graphic3d_ZLayerId aZLayer = (Graphic3d_ZLayerId)Draw::Atoi (theArgVec[anArgIter]);
+      if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer) ||
+          aZLayer == Graphic3d_ZLayerId_UNKNOWN)
+      {
+        Message::SendFail() << "Error: invalid layer " << aZLayer << ".";
+        return 1;
+      }
+      aParams.TargetZLayerId = aZLayer;
+    }
+    else if (anArg == "-singlelayer")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        Message::SendFail() << "Error: integer value is expected right after 'singlelayer'";
+        return 1;
+      }
+      Graphic3d_ZLayerId aZLayer = (Graphic3d_ZLayerId)Draw::Atoi (theArgVec[anArgIter]);
+      if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer) ||
+          aZLayer == Graphic3d_ZLayerId_UNKNOWN)
+      {
+        Message::SendFail() << "Error: invalid layer " << aZLayer << ".";
+        return 1;
+      }
+      aParams.TargetZLayerId = aZLayer;
+      aParams.IsSingleLayer = Standard_True;
+    }
     else
     {
       Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
@@ -1174,6 +1240,7 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
     case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
     case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
     case Graphic3d_BT_Red:                 aFormat = Image_Format_Gray;  break;
+    case Graphic3d_BT_ShadowMap:           aFormat = Image_Format_GrayF;  break;
   }
 
   const bool wasImmUpdate = aView->SetImmediateUpdate (false);
@@ -1194,8 +1261,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
             || aPixMap.SizeY() != Standard_Size(aParams.Height))
       {
-        theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
-              << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
+        if (aParams.BufferType != Graphic3d_BT_ShadowMap)
+        {
+          theDI << "Fail: dumped dimensions " << (Standard_Integer)aPixMap.SizeX() << "x" << (Standard_Integer)aPixMap.SizeY()
+            << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
+        }
       }
       break;
     }
@@ -6784,6 +6854,9 @@ vdump <filename>.png [-width Width -height Height]
       [-stereo mono|left|right|blend|sideBySide|overUnder=mono]
       [-xrPose base|head|handLeft|handRight=base]
       [-tileSize Size=0]
+      [-grouplayer zlayerId]
+      [-singlelayer zlayerId]
+      [-buffer shadowmap lightname]
 Dumps content of the active view into image file.
 )" /* [vdump] */);
 
diff --git a/tests/v3d/bugs/bug32752 b/tests/v3d/bugs/bug32752
new file mode 100644 (file)
index 0000000..90b630e
--- /dev/null
@@ -0,0 +1,88 @@
+puts "========"
+puts "0032752: Visualization, TKOpenGl - extend V3d_View::ToPixMap() options with Z-layer"
+puts "========"
+puts ""
+
+pload MODELING VISUALIZATION
+vclear
+vinit
+box b1 20 0 0 10 10 10
+box b2 -20 0 0 10 10 10
+box b3 0 -10 0 5 5 5
+box b4 0 5 0 5 5 5
+box b5 0 0 5 3 3 3
+box b6 0 0 -5 7 7 7
+box b7 0 -5 -10 3 3 3
+
+set aLayerId1 [vzlayer -add -enable depthTest -enable depthWrite -disable depthClear]
+set aLayerId2 [vzlayer -add -enable depthTest -enable depthWrite -disable depthClear]
+
+vdisplay -dispmode 1 -layer ${aLayerId1} b1
+vdisplay -dispmode 1 -layer ${aLayerId2} b2
+vdisplay -dispmode 1 -layer 0 b3
+vdisplay -dispmode 1 -layer -2 b4
+vdisplay -dispmode 1 -layer -3 b5
+vdisplay -dispmode 1 -layer -4 b6
+vdisplay -dispmode 1 -layer -5 b7
+vfit
+vviewparams -scale 15.0 -proj 0.57735 -0.57735 0.57735 -up -0.1 0.1 0.1 -at 0.0 0.0 0.0
+
+vsetcolor b1 RED3
+vsetcolor b2 GREEN3
+vsetcolor b3 BLUE3
+vsetcolor b4 ORANGE3
+vsetcolor b5 YELLOW3
+vsetcolor b6 SALMON3
+vsetcolor b7 PURPLE3
+
+#dump entire scene
+#color
+vdump $imagedir/${casename}_all.png
+#depth
+vdump $imagedir/${casename}_depth.png -buffer depth
+
+#dump single layer
+vdump $imagedir/${casename}_only_b1.png -singlelayer ${aLayerId1}
+vdump $imagedir/${casename}_only_b2.png -singlelayer ${aLayerId2}
+vdump $imagedir/${casename}_only_b3.png -singlelayer 0
+vdump $imagedir/${casename}_only_b4.png -singlelayer -2
+vdump $imagedir/${casename}_only_b5.png -singlelayer -3
+vdump $imagedir/${casename}_only_b6.png -singlelayer -4
+vdump $imagedir/${casename}_only_b7.png -singlelayer -5
+
+#dump a group of layers
+vdump $imagedir/${casename}_upto_b1.png -grouplayer ${aLayerId1}
+vdump $imagedir/${casename}_upto_b2.png -grouplayer ${aLayerId2}
+vdump $imagedir/${casename}_upto_b3.png -grouplayer 0
+vdump $imagedir/${casename}_upto_b4.png -grouplayer -2
+vdump $imagedir/${casename}_upto_b5.png -grouplayer -3
+vdump $imagedir/${casename}_upto_b6.png -grouplayer -4
+vdump $imagedir/${casename}_upto_b7.png -grouplayer -5
+
+#dump single layer depth values
+vdump $imagedir/${casename}_only_b1_depth.png -buffer depth -singlelayer ${aLayerId1}
+vdump $imagedir/${casename}_only_b2_depth.png -buffer depth -singlelayer ${aLayerId2}
+vdump $imagedir/${casename}_only_b3_depth.png -buffer depth -singlelayer 0
+vdump $imagedir/${casename}_only_b4_depth.png -buffer depth -singlelayer -2
+vdump $imagedir/${casename}_only_b5_depth.png -buffer depth -singlelayer -3
+vdump $imagedir/${casename}_only_b6_depth.png -buffer depth -singlelayer -4
+vdump $imagedir/${casename}_only_b7_depth.png -buffer depth -singlelayer -5
+
+#dump a group of layers depth values
+vdump $imagedir/${casename}_upto_b1_depth.png -buffer depth -grouplayer ${aLayerId1}
+vdump $imagedir/${casename}_upto_b2_depth.png -buffer depth -grouplayer ${aLayerId2}
+vdump $imagedir/${casename}_upto_b3_depth.png -buffer depth -grouplayer 0
+vdump $imagedir/${casename}_upto_b4_depth.png -buffer depth -grouplayer -2
+vdump $imagedir/${casename}_upto_b5_depth.png -buffer depth -grouplayer -3
+vdump $imagedir/${casename}_upto_b6_depth.png -buffer depth -grouplayer -4
+vdump $imagedir/${casename}_upto_b7_depth.png -buffer depth -grouplayer -5
+
+#dump shadow maps
+vlight -clear
+vlight v1 -type directional -intensity 1 -dir -1 0 -0.5 -castShadows 1
+vlight v2 -type directional -intensity 1 -dir -1 0.1 0 -castShadows 1
+#dump scene
+vdump $imagedir/${casename}_newlights.png
+#dump shadowmaps
+vdump $imagedir/${casename}_shadowmap_v1.png -buffer shadowmap v1
+vdump $imagedir/${casename}_shadowmap_v2.png -buffer shadowmap v2