0031621: Draw Harness - handle navigation keys
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands.cxx
index 1022ba9..498ec55 100644 (file)
@@ -71,6 +71,7 @@
 #include <TColgp_Array1OfPnt2d.hxx>
 #include <TColStd_MapOfAsciiString.hxx>
 #include <ViewerTest_AutoUpdater.hxx>
+#include <ViewerTest_ContinuousRedrawer.hxx>
 #include <ViewerTest_EventManager.hxx>
 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
@@ -1397,9 +1398,9 @@ static LRESULT WINAPI AdvViewerWindowProc(
 //purpose  :
 //==============================================================================
 
-const Handle(Standard_Transient)& ViewerTest::WClass()
+const Handle(WNT_WClass)& ViewerTest::WClass()
 {
-  static Handle(Standard_Transient) theWClass;
+  static Handle(WNT_WClass) theWClass;
 #if defined(_WIN32)
   if (theWClass.IsNull())
   {
@@ -1640,120 +1641,6 @@ TCollection_AsciiString ViewerTest::GetCurrentViewName ()
   return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
 }
 
-//! Auxiliary tool performing continuous redraws of specified window.
-class ViewerTest_ContinuousRedrawer
-{
-public:
-  //! Return global instance.
-  static ViewerTest_ContinuousRedrawer& Instance()
-  {
-    static ViewerTest_ContinuousRedrawer aRedrawer;
-    return aRedrawer;
-  }
-public:
-
-  //! Destructor.
-  ~ViewerTest_ContinuousRedrawer()
-  {
-    Stop();
-  }
-
-  //! Start thread.
-  void Start (const Handle(Aspect_Window)& theWindow,
-              Standard_Real theTargetFps)
-  {
-    if (myWindow != theWindow
-     || myTargetFps != theTargetFps)
-    {
-      Stop();
-      myWindow = theWindow;
-      myTargetFps = theTargetFps;
-    }
-    if (myThread.GetId() == 0)
-    {
-      myToStop = false;
-      myThread.Run (this);
-    }
-  }
-
-  //! Stop thread.
-  void Stop (const Handle(Aspect_Window)& theWindow = NULL)
-  {
-    if (!theWindow.IsNull()
-      && myWindow != theWindow)
-    {
-      return;
-    }
-
-    {
-      Standard_Mutex::Sentry aLock (myMutex);
-      myToStop = true;
-    }
-    myThread.Wait();
-    myToStop = false;
-    myWindow.Nullify();
-  }
-
-private:
-
-  //! Thread loop.
-  void doThreadLoop()
-  {
-    Handle(Aspect_DisplayConnection) aDisp = new Aspect_DisplayConnection();
-    OSD_Timer aTimer;
-    aTimer.Start();
-    Standard_Real aTimeOld = 0.0;
-    const Standard_Real aTargetDur = myTargetFps > 0.0 ? 1.0 / myTargetFps : -1.0;
-    for (;;)
-    {
-      {
-        Standard_Mutex::Sentry aLock (myMutex);
-        if (myToStop)
-        {
-          return;
-        }
-      }
-      if (myTargetFps > 0.0)
-      {
-        const Standard_Real aTimeNew  = aTimer.ElapsedTime();
-        const Standard_Real aDuration = aTimeNew - aTimeOld;
-        if (aDuration >= aTargetDur)
-        {
-          myWindow->InvalidateContent (aDisp);
-          aTimeOld = aTimeNew;
-        }
-      }
-      else
-      {
-        myWindow->InvalidateContent (aDisp);
-      }
-
-      OSD::MilliSecSleep (1);
-    }
-  }
-
-  //! Thread creation callback.
-  static Standard_Address doThreadWrapper (Standard_Address theData)
-  {
-    ViewerTest_ContinuousRedrawer* aThis = (ViewerTest_ContinuousRedrawer* )theData;
-    aThis->doThreadLoop();
-    return 0;
-  }
-
-  //! Empty constructor.
-  ViewerTest_ContinuousRedrawer()
-  : myThread (doThreadWrapper),
-    myTargetFps (0.0),
-    myToStop (false) {}
-
-private:
-  Handle(Aspect_Window) myWindow;
-  OSD_Thread      myThread;
-  Standard_Mutex  myMutex;
-  Standard_Real   myTargetFps;
-  volatile bool   myToStop;
-};
-
 //==============================================================================
 //function : ViewerInit
 //purpose  : Create the window viewer and initialize all the global variable
@@ -1939,8 +1826,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
 
   // Create window
 #if defined(_WIN32)
-  VT_GetWindow() = new WNT_Window (aTitle.ToCString(),
-                                    Handle(WNT_WClass)::DownCast (WClass()),
+  VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
                                     Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW,
                                     aPxLeft, aPxTop,
                                     aPxWidth, aPxHeight,
@@ -2152,7 +2038,7 @@ static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const cha
       }
       else
       {
-        std::cout << "Syntax error: unknown argument " << anArg << ".\n";
+        Message::SendFail() << "Syntax error: unknown argument " << anArg;
         return 1;
       }
     }
@@ -2162,7 +2048,7 @@ static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const cha
     }
     else
     {
-      std::cout << "Syntax error: unknown argument " << anArg << ".\n";
+      Message::SendFail() << "Syntax error: unknown argument " << anArg;
       return 1;
     }
   }
@@ -2171,7 +2057,7 @@ static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const cha
   if (!aDisplayName.IsEmpty())
   {
     aDisplayName.Clear();
-    std::cout << "Warning: display parameter will be ignored.\n";
+    Message::SendWarning() << "Warning: display parameter will be ignored.\n";
   }
 #endif
 
@@ -2229,7 +2115,7 @@ static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
   const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
   if (aView.IsNull())
   {
-    std::cerr << "Error: No opened viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -2279,7 +2165,7 @@ static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
     }
     else
     {
-      std::cout << "Syntax error at '" << argv[anArgIter] << "'\n";
+      Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
       return 1;
     }
   }
@@ -2347,7 +2233,7 @@ static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** arg
   const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
   if (aView.IsNull())
   {
-    std::cerr << "Error: No opened viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -2383,14 +2269,14 @@ static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** arg
       TCollection_AsciiString aName (argv[anArgIter]);
       if (!aMap.IsBound2 (aName))
       {
-        std::cout << "Syntax error: Wrong shape name '" << aName << "'.\n";
+        Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
         return 1;
       }
 
       Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
       if (aShape.IsNull())
       {
-        std::cout << "Syntax error: '" << aName << "' is not a shape presentation.\n";
+        Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
         return 1;
       }
       aListOfShapes.Append (aShape);
@@ -2399,7 +2285,7 @@ static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** arg
   }
   if (aTypeOfHLR == Prs3d_TOH_NotSet)
   {
-    std::cout << "Syntax error: wrong number of arguments!\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -2511,7 +2397,7 @@ void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const S
 {
   if (!ViewerTest_myViews.IsBound1(theViewName))
   {
-    std::cout << "Wrong view name\n";
+    Message::SendFail() << "Wrong view name";
     return;
   }
 
@@ -2592,7 +2478,7 @@ void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const S
       ViewerTest_myContexts.UnBind2(aCurrentContext);
     }
   }
-  std::cout << "3D View - " << theViewName << " was deleted.\n";
+  Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
   if (ViewerTest_EventManager::ToExitOnCloseView())
   {
     Draw_Interprete ("exit");
@@ -2632,7 +2518,7 @@ static int VClose (Draw_Interpretor& /*theDi*/,
       ViewerTest_Names aViewName (theArgVec[1]);
       if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
       {
-        std::cerr << "The view with name '" << theArgVec[1] << "' does not exist\n";
+        Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
         return 1;
       }
       aViewList.Append (aViewName.GetViewName());
@@ -2643,7 +2529,7 @@ static int VClose (Draw_Interpretor& /*theDi*/,
     // close active view
     if (ViewerTest::CurrentView().IsNull())
     {
-      std::cerr << "No active view!\n";
+      Message::SendFail ("Error: no active view");
       return 1;
     }
     aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
@@ -2702,7 +2588,7 @@ static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
     }
     else
     {
-      std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+      Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
       return 1;
     }
   }
@@ -2713,7 +2599,7 @@ static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
   }
   else if (aNameString.IsEmpty())
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -2829,7 +2715,7 @@ static int VViewProj (Draw_Interpretor& ,
   const Handle(V3d_View)& aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << "Error: no active view\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -3053,7 +2939,7 @@ static int VViewProj (Draw_Interpretor& ,
         gp_Dir aRight, anUp;
         if (aFrameDef.Value (2) == aFrameDef.Value (4))
         {
-          std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+          Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
           return 1;
         }
 
@@ -3071,7 +2957,7 @@ static int VViewProj (Draw_Interpretor& ,
         }
         else
         {
-          std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+          Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
           return 1;
         }
 
@@ -3089,7 +2975,7 @@ static int VViewProj (Draw_Interpretor& ,
         }
         else
         {
-          std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+          Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
           return 1;
         }
 
@@ -3106,7 +2992,7 @@ static int VViewProj (Draw_Interpretor& ,
       }
       else
       {
-        std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+        Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
         return 1;
       }
     }
@@ -3115,7 +3001,7 @@ static int VViewProj (Draw_Interpretor& ,
   if (!isGeneralCmd
     && theNbArgs != 1)
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
   return 0;
@@ -3135,12 +3021,19 @@ static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
   di << "B : BottomView\n";
   di << "R : RightView\n";
   di << "L : LeftView\n";
-  di << "A : AxonometricView\n";
-  di << "D : ResetView\n";
+  di << "Backspace : AxonometricView\n";
+
+  di << "=========================\n";
+  di << "W, S : Fly   forward/backward\n";
+  di << "A, D : Slide left/right\n";
+  di << "Q, E : Bank  left/right\n";
+  di << "-, + : Change flying speed\n";
+  di << "Arrows : look left/right/up/down\n";
+  di << "Arrows+Shift : slide left/right/up/down\n";
 
   di << "=========================\n";
-  di << "S : Shading\n";
-  di << "W : Wireframe\n";
+  di << "S + Ctrl : Shading\n";
+  di << "W + Ctrl : Wireframe\n";
   di << "H : HiddenLineRemoval\n";
   di << "U : Unset display mode\n";
   di << "Delete : Remove selection from viewer\n";
@@ -3654,7 +3547,7 @@ static void VProcessEvents (ClientData theDispX, int)
   }
   if (aDispConn.IsNull())
   {
-    std::cerr << "Error: ViewerTest is unable processing messages for unknown X Display\n";
+    Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
     return;
   }
 
@@ -3750,7 +3643,7 @@ static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const c
   const Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << "Error: no active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -3771,7 +3664,7 @@ static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const c
     }
     else
     {
-      std::cout << "Syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
     }
   }
 
@@ -3792,7 +3685,7 @@ static int VFitArea (Draw_Interpretor& theDI, Standard_Integer  theArgNb, const
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << theArgVec[0] << "Error: No active view.\n";
+    Message::SendFail ("Error: No active viewer");
     return 1;
   }
 
@@ -3818,7 +3711,7 @@ static int VFitArea (Draw_Interpretor& theDI, Standard_Integer  theArgNb, const
   }
   else
   {
-    std::cerr << theArgVec[0] << "Error: Invalid number of arguments.\n";
+    Message::SendFail ("Syntax error: Invalid number of arguments");
     theDI.PrintHelp(theArgVec[0]);
     return 1;
   }
@@ -3836,7 +3729,7 @@ static int VFitArea (Draw_Interpretor& theDI, Standard_Integer  theArgNb, const
 
   if (aDiagonal < Precision::Confusion())
   {
-    std::cerr << theArgVec[0] << "Error: view area is too small.\n";
+    Message::SendFail ("Error: view area is too small");
     return 1;
   }
 
@@ -3855,7 +3748,7 @@ static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const
 
   if (aCurrentView.IsNull())
   {
-    std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -3888,7 +3781,7 @@ static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char**
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << "Error: no active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -3931,7 +3824,7 @@ static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char**
     }
     else
     {
-      std::cout << "Syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
@@ -3977,7 +3870,7 @@ static int VPick (Draw_Interpretor& ,
 
   if (theNbArgs < 4)
   {
-    std::cout << "Syntax error: Invalid number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -4049,7 +3942,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << "Error: no active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -4089,7 +3982,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4129,7 +4022,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
       }
       else
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
         return 1;
       }
     }
@@ -4137,7 +4030,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4155,14 +4048,14 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
       }
       else
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
       }
     }
     else if (aFlag == "-scale")
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4173,7 +4066,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4184,7 +4077,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4194,7 +4087,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4208,7 +4101,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
                                                            aLabelsColor);
       if (aNbParsed == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
       anArgIter += aNbParsed;
@@ -4220,7 +4113,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
                                                            anArrowColorX);
       if (aNbParsed == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
       anArgIter += aNbParsed;
@@ -4232,7 +4125,7 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
                                                            anArrowColorY);
       if (aNbParsed == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
       anArgIter += aNbParsed;
@@ -4244,14 +4137,14 @@ static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
                                                            anArrowColorZ);
       if (aNbParsed == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
       anArgIter += aNbParsed;
     }
     else
     {
-      std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+      Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
       return 1;
     }
   }
@@ -4273,7 +4166,7 @@ static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, cons
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << "No active view!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -4289,7 +4182,7 @@ static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, cons
       hasFlags = Standard_True;
       if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4302,7 +4195,7 @@ static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, cons
       hasFlags = Standard_True;
       if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4313,7 +4206,7 @@ static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, cons
     else if (theArgNb != 4
           && theArgNb != 7)
     {
-      std::cout << "Error: wrong syntax at '" << anArg << "'\n";
+      Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
       return 1;
     }
   }
@@ -4344,7 +4237,7 @@ static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, cons
     return 0;
   }
 
-  std::cout << "Error: Invalid number of arguments\n";
+  Message::SendFail ("Error: Invalid number of arguments");
   return 1;
 }
 
@@ -4400,13 +4293,13 @@ static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << theArgs[0] << "Error: no active view." << std::endl;
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
   if (theArgNb != 3)
   {
-    std::cerr << theArgs[0] << "Error: invalid number of arguments." << std::endl;
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -4423,12 +4316,12 @@ static int VColorScale (Draw_Interpretor& theDI,
   Handle(V3d_View)               aView    = ViewerTest::CurrentView();
   if (aContext.IsNull())
   {
-    std::cout << "Error: no active view!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   if (theArgNb <= 1)
   {
-    std::cout << "Error: wrong syntax at command '" << theArgVec[0] << "'!\n";
+    Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
     return 1;
   }
 
@@ -4439,7 +4332,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
     if (aColorScale.IsNull())
     {
-      std::cout << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale!\n";
+      Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
       return 1;
     }
   }
@@ -4448,7 +4341,7 @@ static int VColorScale (Draw_Interpretor& theDI,
   {
     if (aColorScale.IsNull())
     {
-      std::cout << "Syntax error: colorscale with a given name does not exist.\n";
+      Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
       return 1;
     }
 
@@ -4499,7 +4392,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 3 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4509,12 +4402,12 @@ static int VColorScale (Draw_Interpretor& theDI,
       if (!aRangeMin.IsRealValue()
        || !aRangeMax.IsRealValue())
       {
-        std::cout << "Error: the range values should be real!\n";
+        Message::SendFail ("Syntax error: the range values should be real");
         return 1;
       }
       else if (!aNbIntervals.IsIntegerValue())
       {
-        std::cout << "Error: the number of intervals should be integer!\n";
+        Message::SendFail ("Syntax error: the number of intervals should be integer");
         return 1;
       }
 
@@ -4525,13 +4418,13 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
       if (!aFontArg.IsIntegerValue())
       {
-        std::cout << "Error: HeightFont value should be integer!\n";
+        Message::SendFail ("Syntax error: HeightFont value should be integer");
         return 1;
       }
 
@@ -4542,7 +4435,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4567,7 +4460,7 @@ static int VColorScale (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: unknown position '" << aTextPosArg << "'!\n";
+        Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
         return 1;
       }
       aColorScale->SetLabelPosition (aLabPosition);
@@ -4577,14 +4470,14 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Synta error at argument '" << anArg << "'";
         return 1;
       }
 
       Standard_Boolean IsLog;
       if (!ViewerTest::ParseOnOff(theArgVec[++anArgIter], IsLog))
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       aColorScale->SetLogarithmic (IsLog);
@@ -4594,7 +4487,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4616,7 +4509,7 @@ static int VColorScale (Draw_Interpretor& theDI,
       if (aNbParsed1 == 0
        || aNbParsed2 == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
 
@@ -4650,7 +4543,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4659,7 +4552,7 @@ static int VColorScale (Draw_Interpretor& theDI,
       if (!anX.IsIntegerValue()
        || !anY.IsIntegerValue())
       {
-        std::cout << "Error: coordinates should be integer values!\n";
+        Message::SendFail ("Syntax error: coordinates should be integer values");
         return 1;
       }
 
@@ -4671,14 +4564,14 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
       if (!aBreadth.IsIntegerValue())
       {
-        std::cout << "Error: a width should be an integer value!\n";
+        Message::SendFail ("Syntax error: a width should be an integer value");
         return 1;
       }
       aColorScale->SetBreadth (aBreadth.IntegerValue());
@@ -4688,14 +4581,14 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
       if (!aHeight.IsIntegerValue())
       {
-        std::cout << "Error: a width should be an integer value!\n";
+        Message::SendFail ("Syntax error: a width should be an integer value");
         return 1;
       }
       aColorScale->SetHeight (aHeight.IntegerValue());
@@ -4704,25 +4597,25 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
       {
-        std::cout << "Error: wrong color type! Call -colors before to set user-specified colors!\n";
+        Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
         return 1;
       }
       else if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
       if (!anInd.IsIntegerValue())
       {
-        std::cout << "Error: Index value should be integer!\n";
+        Message::SendFail ("Syntax error: Index value should be integer");
         return 1;
       }
       const Standard_Integer anIndex = anInd.IntegerValue();
       if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
       {
-        std::cout << "Error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals() <<"!\n";
+        Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
         return 1;
       }
 
@@ -4732,7 +4625,7 @@ static int VColorScale (Draw_Interpretor& theDI,
                                                            aColor);
       if (aNbParsed == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
         return 1;
       }
       aColorScale->SetIntervalColor (aColor, anIndex);
@@ -4743,19 +4636,19 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
       {
-        std::cout << "Error: wrong label type! Call -labels before to set user-specified labels!\n";
+        Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
         return 1;
       }
       else if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
       if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
       {
-        std::cout << "Error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals() + 1 <<"!\n";
+        Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
         return 1;
       }
 
@@ -4791,7 +4684,7 @@ static int VColorScale (Draw_Interpretor& theDI,
         }
         if (aLabAtBorder == -1)
         {
-          std::cout << "Syntax error at argument '" << anArg << "'!\n";
+          Message::SendFail() << "Syntax error at argument '" << anArg << "'";
           return 1;
         }
         toEnable = (aLabAtBorder == 1);
@@ -4824,20 +4717,28 @@ static int VColorScale (Draw_Interpretor& theDI,
       }
       if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
       {
-        std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
-                  << aColorScale->GetNumberOfIntervals() << " intervals\n";
+        Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
+                            << aColorScale->GetNumberOfIntervals() << " intervals";
         return 1;
       }
 
       aColorScale->SetColors    (aSeq);
       aColorScale->SetColorType (Aspect_TOCSD_USER);
     }
+    else if (aFlag == "-uniform")
+    {
+      const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
+      const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
+      const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
+      aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
+      aColorScale->SetColorType (Aspect_TOCSD_USER);
+    }
     else if (aFlag == "-labels"
           || aFlag == "-freelabels")
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Syntax error at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4851,7 +4752,7 @@ static int VColorScale (Draw_Interpretor& theDI,
       }
       if (anArgIter + aNbLabels >= theArgNb)
       {
-        std::cout << "Error: not enough arguments! " << aNbLabels << " text labels are expected.\n";
+        Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
         return 1;
       }
 
@@ -4867,7 +4768,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4924,7 +4825,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -4932,7 +4833,7 @@ static int VColorScale (Draw_Interpretor& theDI,
 
       if (!anArg1.IsRealValue())
       {
-        std::cout << "Error: the value should be real!\n";
+        Message::SendFail ("Syntax error: the value should be real");
         return 1;
       }
 
@@ -4943,7 +4844,7 @@ static int VColorScale (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: wrong syntax at " << anArg << " - unknown argument!\n";
+      Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
       return 1;
     }
   }
@@ -4985,9 +4886,9 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
 {
   if (theArgNum < 2)
   {
-    std::cout << theArgs[0] << " error: wrong number of parameters. Type 'help"
-              << theArgs[0] <<"' for more information.\n";
-    return 1;  //TCL_ERROR
+    Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
+                        << theArgs[0] <<"' for more information";
+    return 1;
   }
 
   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
@@ -5080,15 +4981,15 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
     aLowerKey  = "-";
     aLowerKey += aKey;
     aLowerKey.LowerCase();
-    std::cout << theArgs[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
-    std::cout << "Type help for more information.\n";
+    Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
+                        << "Type help for more information";
     return 1;
   }
 
   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
   if (anAISContext.IsNull())
   {
-    std::cout << theArgs[0] << ":  please use 'vinit' command to initialize view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -5145,7 +5046,7 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
   {
     if (!GetColor (aValues->Value(1), aColor))
     {
-      std::cout << theArgs[0] << "error: -xnamecolor wrong color name.\n";
+      Message::SendFail ("Syntax error: -xnamecolor wrong color name");
       return 1;
     }
     aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
@@ -5154,7 +5055,7 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
   {
     if (!GetColor (aValues->Value(1), aColor))
     {
-      std::cout << theArgs[0] << "error: -ynamecolor wrong color name.\n";
+      Message::SendFail ("Syntax error: -ynamecolor wrong color name");
       return 1;
     }
     aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
@@ -5163,7 +5064,7 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
   {
     if (!GetColor (aValues->Value(1), aColor))
     {
-      std::cout << theArgs[0] << "error: -znamecolor wrong color name.\n";
+      Message::SendFail ("Syntax error: -znamecolor wrong color name");
       return 1;
     }
     aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
@@ -5172,7 +5073,7 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
   {
     if (!GetColor (aValues->Value(1), aColor))
     {
-      std::cout << theArgs[0] << "error: -xcolor wrong color name.\n";
+      Message::SendFail ("Syntax error: -xcolor wrong color name");
       return 1;
     }
     aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
@@ -5181,7 +5082,7 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
   {
     if (!GetColor (aValues->Value(1), aColor))
     {
-      std::cout << theArgs[0] << "error: -ycolor wrong color name.\n";
+      Message::SendFail ("Syntax error: -ycolor wrong color name");
       return 1;
     }
     aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
@@ -5190,7 +5091,7 @@ static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer th
   {
     if (!GetColor (aValues->Value(1), aColor))
     {
-      std::cout << theArgs[0] << "error: -zcolor wrong color name.\n";
+      Message::SendFail ("Syntax error: -zcolor wrong color name");
       return 1;
     }
     aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
@@ -5312,7 +5213,7 @@ static int VTile (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "Error: no active viewer.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -5335,7 +5236,7 @@ static int VTile (Draw_Interpretor& theDI,
     {
       if (anArgIter + 3 < theArgNb)
       {
-        std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
+        Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
         return 1;
       }
       aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
@@ -5348,7 +5249,7 @@ static int VTile (Draw_Interpretor& theDI,
     {
       if (anArgIter + 3 < theArgNb)
       {
-        std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
+        Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
         return 1;
       }
       aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
@@ -5356,7 +5257,7 @@ static int VTile (Draw_Interpretor& theDI,
       if (aTile.TotalSize.x() < 1
        || aTile.TotalSize.y() < 1)
       {
-        std::cerr << "Error: total size is incorrect.\n";
+        Message::SendFail ("Error: total size is incorrect");
         return 1;
       }
     }
@@ -5364,7 +5265,7 @@ static int VTile (Draw_Interpretor& theDI,
     {
       if (anArgIter + 3 < theArgNb)
       {
-        std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
+        Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
         return 1;
       }
 
@@ -5373,7 +5274,7 @@ static int VTile (Draw_Interpretor& theDI,
       if (aTile.TileSize.x() < 1
        || aTile.TileSize.y() < 1)
       {
-        std::cerr << "Error: tile size is incorrect.\n";
+        Message::SendFail ("Error: tile size is incorrect");
         return 1;
       }
     }
@@ -5388,13 +5289,13 @@ static int VTile (Draw_Interpretor& theDI,
   if (aTile.TileSize.x() < 1
    || aTile.TileSize.y() < 1)
   {
-    std::cerr << "Error: tile size is undefined.\n";
+    Message::SendFail ("Error: tile size is undefined");
     return 1;
   }
   else if (aTile.TotalSize.x() < 1
         || aTile.TotalSize.y() < 1)
   {
-    std::cerr << "Error: total size is undefined.\n";
+    Message::SendFail ("Error: total size is undefined");
     return 1;
   }
 
@@ -5453,7 +5354,7 @@ static int VZLayer (Draw_Interpretor& theDI,
   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
   if (aContextAIS.IsNull())
   {
-    std::cout << "No active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -5511,7 +5412,7 @@ static int VZLayer (Draw_Interpretor& theDI,
       aLayerId = Graphic3d_ZLayerId_UNKNOWN;
       if (!aViewer->AddZLayer (aLayerId))
       {
-        std::cout << "Error: can not add a new z layer!\n";
+        Message::SendFail ("Error: can not add a new z layer");
         return 0;
       }
 
@@ -5525,7 +5426,7 @@ static int VZLayer (Draw_Interpretor& theDI,
       aLayerId = Graphic3d_ZLayerId_UNKNOWN;
       if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
       {
-        std::cout << "Error: can not add a new z layer!\n";
+        Message::SendFail ("Error: can not add a new z layer");
         return 0;
       }
 
@@ -5539,7 +5440,7 @@ static int VZLayer (Draw_Interpretor& theDI,
       aLayerId = Graphic3d_ZLayerId_UNKNOWN;
       if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
       {
-        std::cout << "Error: can not add a new z layer!\n";
+        Message::SendFail ("Error: can not add a new z layer");
         return 0;
       }
 
@@ -5553,7 +5454,7 @@ static int VZLayer (Draw_Interpretor& theDI,
       {
         if (++anArgIter >= theArgNb)
         {
-          std::cout << "Syntax error: id of z layer to remove is missing\n";
+          Message::SendFail ("Syntax error: id of z layer to remove is missing");
           return 1;
         }
 
@@ -5567,7 +5468,7 @@ static int VZLayer (Draw_Interpretor& theDI,
        || aLayerId == Graphic3d_ZLayerId_TopOSD
        || aLayerId == Graphic3d_ZLayerId_BotOSD)
       {
-        std::cout << "Syntax error: standard Z layer can not be removed\n";
+        Message::SendFail ("Syntax error: standard Z layer can not be removed");
         return 1;
       }
 
@@ -5586,7 +5487,7 @@ static int VZLayer (Draw_Interpretor& theDI,
 
       if (!aViewer->RemoveZLayer (aLayerId))
       {
-        std::cout << "Z layer can not be removed!\n";
+        Message::SendFail ("Z layer can not be removed");
       }
       else
       {
@@ -5609,13 +5510,13 @@ static int VZLayer (Draw_Interpretor& theDI,
     {
       if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
       {
-        std::cout << "Syntax error: id of Z layer is missing\n";
+        Message::SendFail ("Syntax error: id of Z layer is missing");
         return 1;
       }
 
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error: name is missing\n";
+        Message::SendFail ("Syntax error: name is missing");
         return 1;
       }
 
@@ -5627,13 +5528,13 @@ static int VZLayer (Draw_Interpretor& theDI,
     {
       if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
       {
-        std::cout << "Syntax error: id of Z layer is missing\n";
+        Message::SendFail ("Syntax error: id of Z layer is missing");
         return 1;
       }
 
       if (anArgIter + 2 >= theArgNb)
       {
-        std::cout << "Syntax error: origin coordinates are missing\n";
+        Message::SendFail ("Syntax error: origin coordinates are missing");
         return 1;
       }
 
@@ -5688,7 +5589,7 @@ static int VZLayer (Draw_Interpretor& theDI,
       {
         if (++anArgIter >= theArgNb)
         {
-          std::cout << "Syntax error: id of Z layer is missing\n";
+          Message::SendFail ("Syntax error: id of Z layer is missing");
           return 1;
         }
 
@@ -5707,7 +5608,7 @@ static int VZLayer (Draw_Interpretor& theDI,
                                      || anArg == "enable";
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error: option name is missing\n";
+        Message::SendFail ("Syntax error: option name is missing");
         return 1;
       }
 
@@ -5717,7 +5618,7 @@ static int VZLayer (Draw_Interpretor& theDI,
       {
         if (++anArgIter >= theArgNb)
         {
-          std::cout << "Syntax error: id of Z layer is missing\n";
+          Message::SendFail ("Syntax error: id of Z layer is missing");
           return 1;
         }
 
@@ -5749,7 +5650,7 @@ static int VZLayer (Draw_Interpretor& theDI,
         {
           if (anArgIter + 2 >= theArgNb)
           {
-            std::cout << "Syntax error: factor and units values for depth offset are missing\n";
+            Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
             return 1;
           }
 
@@ -5795,7 +5696,7 @@ static int VZLayer (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Syntax error: unknown option " << theArgVec[anArgIter] << "\n";
+      Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
       return 1;
     }
   }
@@ -5914,7 +5815,7 @@ static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char**
   if (argc > 6
   && !ViewerTest::ParseLineType (argv[6], aLineType))
   {
-    std::cout << "Syntax error: unknown line type '" << argv[6] << "'\n";
+    Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
     return 1;
   }
 
@@ -5957,7 +5858,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
   if (aView.IsNull() || aViewer.IsNull())
   {
-    std::cerr << "Error: no active view\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -5994,7 +5895,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
       }
       else
       {
-        std::cout << "Syntax error at '" << anArgNext << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArgNext << "'";
         return 1;
       }
     }
@@ -6017,7 +5918,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
       }
       else
       {
-        std::cout << "Syntax error at '" << anArgNext << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArgNext << "'";
         return 1;
       }
     }
@@ -6039,7 +5940,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
       if (aNewStepXY.x() <= 0.0
        || aNewStepXY.y() <= 0.0)
       {
-        std::cout << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'\n";
+        Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
         return 1;
       }
       anArgIter += 2;
@@ -6067,7 +5968,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
       aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
       if (aNewStepXY.x() <= 0.0)
       {
-        std::cout << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'\n";
+        Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
         return 1;
       }
     }
@@ -6080,7 +5981,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
       if (aNewStepXY.x() <= 0.0
        || aNewStepXY.y() <= 0.0)
       {
-        std::cout << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'\n";
+        Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
         return 1;
       }
       anArgIter += 2;
@@ -6117,7 +6018,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
     }
     else
     {
-      std::cout << "Syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
@@ -6173,7 +6074,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
       aDivisionNumber = (int )aNewStepXY[1];
       if (aDivisionNumber < 1)
       {
-        std::cout << "Syntax error: invalid division number '" << aNewStepXY[1] << "'\n";
+        Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
         return 1;
       }
     }
@@ -6192,7 +6093,7 @@ static int VGrid (Draw_Interpretor& /*theDI*/,
         aRadius = aNewSizeXY.x();
         if (aNewSizeXY.y() != 0.0)
         {
-          std::cout << "Syntax error: circular size should be specified as radius\n";
+          Message::SendFail ("Syntax error: circular size should be specified as radius");
           return 1;
         }
       }
@@ -6218,7 +6119,7 @@ static int VPriviledgedPlane (Draw_Interpretor& theDI,
 {
   if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
   {
-    std::cerr << "Error: wrong number of arguments! See usage:\n";
+    Message::SendFail ("Error: wrong number of arguments! See usage:");
     theDI.PrintHelp (theArgVec[0]);
     return 1;
   }
@@ -6227,7 +6128,7 @@ static int VPriviledgedPlane (Draw_Interpretor& theDI,
   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
   if (aViewer.IsNull())
   {
-    std::cerr << "Error: no active viewer. Please call vinit.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -6285,7 +6186,7 @@ static int VConvert (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "Error: no active view. Please call vinit.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -6307,7 +6208,7 @@ static int VConvert (Draw_Interpretor& theDI,
   // non-numeric argument too early
   if (aCoord.IsEmpty())
   {
-    std::cerr << "Error: wrong number of arguments! See usage:\n";
+    Message::SendFail ("Error: wrong number of arguments! See usage:");
     theDI.PrintHelp (theArgVec[0]);
     return 1;
   }
@@ -6323,7 +6224,7 @@ static int VConvert (Draw_Interpretor& theDI,
     else if (anArg == "ray")    aMode = Ray;
     else
     {
-      std::cerr << "Error: wrong argument " << anArg << "! See usage:\n";
+      Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
       theDI.PrintHelp (theArgVec[0]);
       return 1;
     }
@@ -6334,7 +6235,7 @@ static int VConvert (Draw_Interpretor& theDI,
       (aCoord.Length() == 2 && theArgNb > 4) ||
       (aCoord.Length() == 3 && theArgNb > 5))
   {
-    std::cerr << "Error: wrong number of arguments! See usage:\n";
+    Message::SendFail ("Error: wrong number of arguments! See usage:");
     theDI.PrintHelp (theArgVec[0]);
     return 1;
   }
@@ -6350,7 +6251,7 @@ static int VConvert (Draw_Interpretor& theDI,
       case View   : theDI << "View Vv: "   << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
       case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
       default:
-        std::cerr << "Error: wrong arguments! See usage:\n";
+        Message::SendFail ("Error: wrong arguments! See usage:");
         theDI.PrintHelp (theArgVec[0]);
         return 1;
     }
@@ -6391,7 +6292,7 @@ static int VConvert (Draw_Interpretor& theDI,
         return 0;
 
       default:
-        std::cerr << "Error: wrong arguments! See usage:\n";
+        Message::SendFail ("Error: wrong arguments! See usage:");
         theDI.PrintHelp (theArgVec[0]);
         return 1;
     }
@@ -6413,7 +6314,7 @@ static int VConvert (Draw_Interpretor& theDI,
         return 0;
 
       default:
-        std::cerr << "Error: wrong arguments! See usage:\n";
+        Message::SendFail ("Error: wrong arguments! See usage:");
         theDI.PrintHelp (theArgVec[0]);
         return 1;
     }
@@ -6435,7 +6336,7 @@ static int VFps (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "No active view. Please call vinit.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -6459,13 +6360,13 @@ static int VFps (Draw_Interpretor& theDI,
       aFramesNb = anArg.IntegerValue();
       if (aFramesNb <= 0)
       {
-        std::cerr << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
     }
     else
     {
-      std::cerr << "Syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
@@ -6719,7 +6620,7 @@ static int VGlDebug (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: wrong syntax at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
@@ -6749,7 +6650,7 @@ static int VVbo (Draw_Interpretor& theDI,
   {
     if (!toSet)
     {
-      std::cerr << "No active view!\n";
+      Message::SendFail ("Error: no active viewer");
     }
     return 1;
   }
@@ -6801,6 +6702,7 @@ static int VCaps (Draw_Interpretor& theDI,
     theDI << "WinBuffer: " << (aCaps->useSystemBuffer ? "1" : "0") << "\n";
     theDI << "NoExt:"    << (aCaps->contextNoExtensions ? "1" : "0") << "\n";
     theDI << "MaxVersion:" << aCaps->contextMajorVersionUpper << "." << aCaps->contextMinorVersionUpper << "\n";
+    theDI << "CompressTextures: " << (aCaps->compressedTexturesDisable ? "0" : "1") << "\n";
     return 0;
   }
 
@@ -6855,6 +6757,16 @@ static int VCaps (Draw_Interpretor& theDI,
       }
       aCaps->sRGBDisable = !toEnable;
     }
+    else if (anArgCase == "-compressedtextures")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aCaps->compressedTexturesDisable = !toEnable;
+    }
     else if (anArgCase == "-vbo")
     {
       Standard_Boolean toEnable = Standard_True;
@@ -6986,7 +6898,7 @@ static int VCaps (Draw_Interpretor& theDI,
       if (aVer[0] < -1
        || aVer[1] < -1)
       {
-        std::cout << "Syntax error at '" << anArgCase << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArgCase << "'";
         return 1;
       }
       aCaps->contextMajorVersionUpper = aVer[0];
@@ -6994,7 +6906,7 @@ static int VCaps (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Error: unknown argument '" << anArg << "'";
       return 1;
     }
   }
@@ -7018,14 +6930,14 @@ static int VMemGpu (Draw_Interpretor& theDI,
   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
   if (aContextAIS.IsNull())
   {
-    std::cerr << "No active view. Please call vinit.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
   if (aDriver.IsNull())
   {
-    std::cerr << "Graphic driver not available.\n";
+    Message::SendFail ("Error: graphic driver not available");
     return 1;
   }
 
@@ -7033,7 +6945,7 @@ static int VMemGpu (Draw_Interpretor& theDI,
   TCollection_AsciiString anInfo;
   if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
   {
-    std::cerr << "Information not available.\n";
+    Message::SendFail ("Error: information not available");
     return 1;
   }
 
@@ -7061,12 +6973,13 @@ static int VReadPixel (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "No active view. Please call vinit.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   else if (theArgNb < 3)
   {
-    std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
+    Message::SendFail() << "Syntax error: wrong number of arguments.\n"
+                        << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
     return 1;
   }
 
@@ -7079,7 +6992,7 @@ static int VReadPixel (Draw_Interpretor& theDI,
   const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
   if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
   {
-    std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
+    Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
     return 1;
   }
 
@@ -7143,7 +7056,7 @@ static int VReadPixel (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Syntax error at '" << aParam << "'\n";
+      Message::SendFail() << "Syntax error at '" << aParam << "'";
       return 1;
     }
   }
@@ -7151,12 +7064,12 @@ static int VReadPixel (Draw_Interpretor& theDI,
   Image_PixMap anImage;
   if (!anImage.InitTrash (aFormat, aWidth, aHeight))
   {
-    std::cerr << "Image allocation failed\n";
+    Message::SendFail ("Error: image allocation failed");
     return 1;
   }
   else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
   {
-    std::cerr << "Image dump failed\n";
+    Message::SendFail ("Error: image dump failed");
     return 1;
   }
 
@@ -7344,7 +7257,7 @@ static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
 {
   if (theArgNb < 3)
   {
-    std::cout << "Syntax error: not enough arguments.\n";
+    Message::SendFail ("Syntax error: not enough arguments");
     return 1;
   }
 
@@ -7370,7 +7283,7 @@ static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
       aTolColor = Atof (theArgVec[++anArgIter]);
       if (aTolColor < 0.0 || aTolColor > 1.0)
       {
-        std::cout << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
         return 1;
       }
     }
@@ -7432,7 +7345,7 @@ static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
       aTolColor = anArg.RealValue();
       if (aTolColor < 0.0 || aTolColor > 1.0)
       {
-        std::cout << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
         return 1;
       }
     }
@@ -7454,7 +7367,7 @@ static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
     }
     else
     {
-      std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+      Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
       return 1;
     }
   }
@@ -7463,12 +7376,12 @@ static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
   Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
   if (!anImgRef->Load (anImgPathRef))
   {
-    std::cout << "Error: image file '" << anImgPathRef << "' cannot be read\n";
+    Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
     return 1;
   }
   if (!anImgNew->Load (anImgPathNew))
   {
-    std::cout << "Error: image file '" << anImgPathNew << "' cannot be read\n";
+    Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
     return 1;
   }
 
@@ -7491,14 +7404,14 @@ static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
     aDiff = new Image_AlienPixMap();
     if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
     {
-      std::cout << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY() << "\n";
+      Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
       return 1;
     }
     aComparer.SaveDiffImage (*aDiff);
     if (!aDiffImagePath.IsEmpty()
      && !aDiff->Save (aDiffImagePath))
     {
-      std::cout << "Error: diff image file '" << aDiffImagePath << "' cannot be written\n";
+      Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
       return 1;
     }
   }
@@ -7591,7 +7504,7 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
   if (aCtx.IsNull())
   {
-    std::cout << "Error: no active View\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -7624,16 +7537,11 @@ static Standard_Integer VSelect (Draw_Interpretor& ,
     }
     else
     {
-      std::cout << "Syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
-  if (toAllowOverlap
-   && aPnts.Length() != 2)
-  {
-    std::cout << "Syntax error: -allowoverlap key is applied only for rectangle selection\n";
-    return 1;
-  }
+
   if (toAllowOverlap)
   {
     aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
@@ -7686,7 +7594,7 @@ static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
   const Handle(V3d_View)&               aView    = ViewerTest::CurrentView();
   if (aContext.IsNull())
   {
-    std::cout << "Error: no active View\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -7700,7 +7608,7 @@ static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 < theNbArgs)
       {
-        std::cout << "Syntax error at '" << theArgVec[anArgIter + 1] << "'\n";
+        Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
         return 1;
       }
 
@@ -7728,7 +7636,7 @@ static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+      Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
       return 1;
     }
   }
@@ -7736,7 +7644,7 @@ static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
   if (aMousePos.x() == IntegerLast()
    || aMousePos.y() == IntegerLast())
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -7934,7 +7842,7 @@ static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, con
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << theArgVec[0] << ": please initialize or activate view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -8099,7 +8007,7 @@ static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, con
     }
     else
     {
-      std::cout << "Syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
@@ -8147,7 +8055,7 @@ static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb,
   Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
   if (aV3dView.IsNull())
   {
-    std::cout << "Error: no active view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
@@ -8162,7 +8070,7 @@ static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb,
       TCollection_AsciiString aViewName = aViewNames.GetViewName();
       if (!ViewerTest_myViews.IsBound1 (aViewName))
       {
-        std::cout << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'.\n";
+        Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
         return 1;
       }
       aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
@@ -8181,7 +8089,7 @@ static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb,
     }
     else
     {
-      std::cout << "Syntax error: unknown argument " << anArg << ".\n";
+      Message::SendFail() << "Syntax error: unknown argument " << anArg;
       return 1;
     }
   }
@@ -8210,7 +8118,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
   }
   if (aCtx.IsNull())
   {
-    std::cout << "Error: no active view\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -8218,7 +8126,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
   TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
   if (aNameArg.IsEmpty())
   {
-    std::cout << "Syntax error: animation name is not defined.\n";
+    Message::SendFail ("Syntax error: animation name is not defined");
     return 1;
   }
 
@@ -8232,7 +8140,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
   }
   else if (aNameArg.Value (1) == '-')
   {
-    std::cout << "Syntax error: invalid animation name '" << aNameArg  << "'.\n";
+    Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg  << "'";
     return 1;
   }
 
@@ -8253,7 +8161,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (aSplitPos == aNameArg.Length())
       {
-        std::cout << "Syntax error: animation name is not defined.\n";
+        Message::SendFail ("Syntax error: animation name is not defined");
         return 1;
       }
 
@@ -8379,7 +8287,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg << "";
         return 1;
       }
       aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
@@ -8402,7 +8310,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8431,7 +8339,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8450,7 +8358,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
         aRecParams.FpsDen = aDenStr.IntegerValue();
         if (aRecParams.FpsDen < 1)
         {
-          std::cout << "Syntax error at " << anArg << ".\n";
+          Message::SendFail() << "Syntax error at " << anArg;
           return 1;
         }
       }
@@ -8459,7 +8367,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       aRecParams.Format = theArgVec[anArgIter];
@@ -8470,7 +8378,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       aRecParams.PixelFormat = theArgVec[anArgIter];
@@ -8481,7 +8389,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       aRecParams.VideoCodec = theArgVec[anArgIter];
@@ -8493,7 +8401,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
       const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8506,7 +8414,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8519,7 +8427,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8531,7 +8439,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8546,7 +8454,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8562,7 +8470,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
 
@@ -8571,7 +8479,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
       Handle(AIS_InteractiveObject) anObject;
       if (!aMapOfAIS.Find2 (anObjName, anObject))
       {
-        std::cout << "Syntax error: wrong object name at " << anArg << "\n";
+        Message::SendFail() << "Syntax error: wrong object name at " << anArg;
         return 1;
       }
 
@@ -8593,7 +8501,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
           if (aTrsfArgIter + 4 >= theArgNb
           || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
           {
-            std::cout << "Syntax error at " << aTrsfArg << ".\n";
+            Message::SendFail() << "Syntax error at " << aTrsfArg;
             return 1;
           }
           aTrsfArgIter += 4;
@@ -8605,7 +8513,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
           if (aTrsfArgIter + 3 >= theArgNb
           || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
           {
-            std::cout << "Syntax error at " << aTrsfArg << ".\n";
+            Message::SendFail() << "Syntax error at " << aTrsfArg;
             return 1;
           }
           aTrsfArgIter += 3;
@@ -8615,14 +8523,14 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
           isTrsfSet = Standard_True;
           if (++aTrsfArgIter >= theArgNb)
           {
-            std::cout << "Syntax error at " << aTrsfArg << ".\n";
+            Message::SendFail() << "Syntax error at " << aTrsfArg;
             return 1;
           }
 
           const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
           if (!aScaleStr.IsRealValue())
           {
-            std::cout << "Syntax error at " << aTrsfArg << ".\n";
+            Message::SendFail() << "Syntax error at " << aTrsfArg;
             return 1;
           }
           aScales[anIndex] = aScaleStr.RealValue();
@@ -8635,7 +8543,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
       }
       if (!isTrsfSet)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       else if (aTrsfArgIter >= theArgNb)
@@ -8681,14 +8589,14 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
           isTrsfSet = Standard_True;
           if (++aViewArgIter >= theArgNb)
           {
-            std::cout << "Syntax error at " << anArg << ".\n";
+            Message::SendFail() << "Syntax error at " << anArg;
             return 1;
           }
 
           const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
           if (!aScaleStr.IsRealValue())
           {
-            std::cout << "Syntax error at " << aViewArg << ".\n";
+            Message::SendFail() << "Syntax error at " << aViewArg;
             return 1;
           }
           Standard_Real aScale = aScaleStr.RealValue();
@@ -8705,7 +8613,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
           if (aViewArgIter + 3 >= theArgNb
           || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
           {
-            std::cout << "Syntax error at " << aViewArg << ".\n";
+            Message::SendFail() << "Syntax error at " << aViewArg;
             return 1;
           }
           aViewArgIter += 3;
@@ -8732,7 +8640,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
       }
       if (!isTrsfSet)
       {
-        std::cout << "Syntax error at " << anArg << ".\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       else if (aViewArgIter >= theArgNb)
@@ -8745,7 +8653,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Syntax error at " << anArg << ".\n";
+      Message::SendFail() << "Syntax error at " << anArg;
       return 1;
     }
   }
@@ -8834,7 +8742,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
       aRecorder = new Image_VideoRecorder();
       if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
       {
-        std::cout << "Error: failed to open video file for recording\n";
+        Message::SendFail ("Error: failed to open video file for recording");
         return 0;
       }
 
@@ -8866,7 +8774,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
         aDumpParams.ToAdjustAspect = Standard_True;
         if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
         {
-          std::cout << "Error: view dump is failed!\n";
+          Message::SendFail ("Error: view dump is failed");
           return 0;
         }
         aFlipper.FlipY (aRecorder->ChangeFrame());
@@ -9158,7 +9066,7 @@ static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "No active view. Please call vinit.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -9202,9 +9110,9 @@ static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb,
 
   if (!isOk)
   {
-    std::cerr << "Usage :" << std::endl;
-    std::cerr << theArgVec[0] << " off" << std::endl;
-    std::cerr << theArgVec[0] << " on {index_of_std_texture(0..7)|texture_file_name} [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} scale_s scale_t translation_s translation_t rotation_degrees]" << std::endl;
+    Message::SendFail() << "Usage:\n"
+                        << theArgVec[0] << " off\n"
+                        << theArgVec[0] << " on {index_of_std_texture(0..7)|texture_file_name} [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} scale_s scale_t translation_s translation_t rotation_degrees]";
     return 1;
   }
 
@@ -9254,7 +9162,7 @@ namespace
     Handle(Graphic3d_ClipPlane) aClipPlane;
     if (!theRegPlanes.Find (theName, aClipPlane))
     {
-      std::cout << "Warning: no such plane.\n";
+      Message::SendWarning ("Warning: no such plane");
       return;
     }
 
@@ -9300,7 +9208,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
   const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
   if (anActiveView.IsNull())
   {
-    std::cout << "Error: no active view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -9323,7 +9231,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
   {
     if (theArgsNb < 3)
     {
-      std::cout << "Syntax error: plane name is required.\n";
+      Message::SendFail ("Syntax error: plane name is required");
       return 1;
     }
 
@@ -9352,19 +9260,19 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (!aRegPlanes.IsBound (aPlane))
       {
-        std::cout << "Error: no such plane.\n";
+        Message::SendFail ("Error: no such plane");
         return 1;
       }
       else if (theArgsNb < 4)
       {
-        std::cout << "Syntax error: enter name for new plane.\n";
+        Message::SendFail ("Syntax error: enter name for new plane");
         return 1;
       }
 
       TCollection_AsciiString aClone (theArgVec[3]);
       if (aRegPlanes.IsBound (aClone))
       {
-        std::cout << "Error: plane name is in use.\n";
+        Message::SendFail ("Error: plane name is in use");
         return 1;
       }
 
@@ -9406,7 +9314,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
   {
     if (theArgsNb < 5)
     {
-      std::cout << "Syntax error: need more arguments.\n";
+      Message::SendFail ("Syntax error: need more arguments");
       return 1;
     }
 
@@ -9433,7 +9341,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     // old syntax support
     if (theArgsNb < 3)
     {
-      std::cout << "Syntax error: need more arguments.\n";
+      Message::SendFail ("Syntax error: need more arguments");
       return 1;
     }
 
@@ -9441,7 +9349,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     aPlaneName = theArgVec[2];
     if (!aRegPlanes.Find (aPlaneName, aClipPlane))
     {
-      std::cout << "Error: no such plane '" << aPlaneName << "'.\n";
+      Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
       return 1;
     }
   }
@@ -9461,7 +9369,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
 
   if (theArgsNb - anArgIter < 1)
   {
-    std::cout << "Syntax error: need more arguments.\n";
+    Message::SendFail ("Syntax error: need more arguments");
     return 1;
   }
 
@@ -9482,7 +9390,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 5)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9494,7 +9402,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
         if (!aSubStr.IsIntegerValue()
           || aSubStr.IntegerValue() <= 0)
         {
-          std::cout << "Syntax error: unknown argument '" << aChangeArg << "'.\n";
+          Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
           return 1;
         }
         aSubIndex = aSubStr.IntegerValue();
@@ -9559,7 +9467,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9580,7 +9488,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9597,7 +9505,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9612,7 +9520,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9631,7 +9539,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
                                                            aColor);
       if (aNbParsed == 0)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
       aClipPlane->SetCappingColor (aColor);
@@ -9645,7 +9553,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
       Graphic3d_NameOfMaterial aMatName;
       if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
       {
-        std::cout << "Syntax error: unknown material '" << aChangeArgs[1] << "'.\n";
+        Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
         return 1;
       }
       aClipPlane->SetCappingMaterial (aMatName);
@@ -9685,7 +9593,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
         }
         else
         {
-          std::cout << "Syntax error at '" << aValStr << "'\n";
+          Message::SendFail() << "Syntax error at '" << aValStr << "'";
           return 1;
         }
         anAspect->SetAlphaMode (aMode);
@@ -9698,7 +9606,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9721,13 +9629,13 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aClipPlane->CappingTexture().IsNull())
       {
-        std::cout << "Error: no texture is set.\n";
+        Message::SendFail ("Error: no texture is set");
         return 1;
       }
 
       if (aNbChangeArgs < 3)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9741,13 +9649,13 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aClipPlane->CappingTexture().IsNull())
       {
-        std::cout << "Error: no texture is set.\n";
+        Message::SendFail ("Error: no texture is set");
         return 1;
       }
 
       if (aNbChangeArgs < 3)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9762,13 +9670,13 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aClipPlane->CappingTexture().IsNull())
       {
-        std::cout << "Error: no texture is set.\n";
+        Message::SendFail ("Error: no texture is set");
         return 1;
       }
 
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9781,7 +9689,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     {
       if (aNbChangeArgs < 2)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
 
@@ -9855,7 +9763,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
         }
         else
         {
-          std::cout << "Error: object/view '" << anEntityName << "' is not found!\n";
+          Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
           return 1;
         }
       }
@@ -9879,7 +9787,7 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
     }
     else
     {
-      std::cout << "Syntax error: unknown argument '" << aChangeArg << "'.\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
       return 1;
     }
   }
@@ -9898,7 +9806,7 @@ static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const c
 
   if (aCurrentView.IsNull())
   {
-    std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -9918,14 +9826,13 @@ static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const c
 
     if (aNewZNear >= aNewZFar)
     {
-      std::cout << theArgVec[0] << ": invalid arguments: znear should be less than zfar.\n";
+      Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
       return 1;
     }
 
     if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
     {
-      std::cout << theArgVec[0] << ": invalid arguments: ";
-      std::cout << "znear, zfar should be positive for perspective camera.\n";
+      Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
       return 1;
     }
 
@@ -9933,7 +9840,7 @@ static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const c
   }
   else
   {
-    std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
+    Message::SendFail ("Syntax error: wrong command arguments");
     return 1;
   }
 
@@ -9952,7 +9859,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
 
   if (aCurrentView.IsNull())
   {
-    std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -9960,7 +9867,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
 
   if (theArgsNb > 3)
   {
-    std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
+    Message::SendFail ("Syntax error: wrong command arguments");
     return 1;
   }
 
@@ -9980,9 +9887,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
   }
 
   aCurrentView->SetAutoZFitMode (isOn, aScale);
-  aCurrentView->AutoZFit();
   aCurrentView->Redraw();
-
   return 0;
 }
 
@@ -10011,7 +9916,7 @@ static int VCamera (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cout << "Error: no active view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -10020,6 +9925,8 @@ static int VCamera (Draw_Interpretor& theDI,
   {
     theDI << "ProjType:   " << projTypeName (aCamera->ProjectionType()) << "\n";
     theDI << "FOVy:       " << aCamera->FOVy() << "\n";
+    theDI << "FOVx:       " << aCamera->FOVx() << "\n";
+    theDI << "FOV2d:      " << aCamera->FOV2d() << "\n";
     theDI << "Distance:   " << aCamera->Distance() << "\n";
     theDI << "IOD:        " << aCamera->IOD() << "\n";
     theDI << "IODType:    " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute   ? "absolute" : "relative") << "\n";
@@ -10124,7 +10031,7 @@ static int VCamera (Draw_Interpretor& theDI,
       }
       else if (*anArgValue != '-')
       {
-        std::cout << "Error: unknown IOD type '" << anArgValue << "'\n";
+        Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
         return 1;
       }
       switch (aCamera->GetIODType())
@@ -10166,7 +10073,7 @@ static int VCamera (Draw_Interpretor& theDI,
       }
       else if (*anArgValue != '-')
       {
-        std::cout << "Error: unknown ZFocus type '" << anArgValue << "'\n";
+        Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
         return 1;
       }
       switch (aCamera->ZFocusType())
@@ -10175,18 +10082,83 @@ static int VCamera (Draw_Interpretor& theDI,
         case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
       }
     }
+    else if (anArgCase == "-lockzup"
+          || anArgCase == "-turntable")
+    {
+      bool toLockUp = true;
+      if (++anArgIter < theArgsNb
+      && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toLockUp))
+      {
+        --anArgIter;
+      }
+      ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
+    }
     else if (anArgCase == "-fov"
-          || anArgCase == "-fovy")
+          || anArgCase == "-fovy"
+          || anArgCase == "-fovx"
+          || anArgCase == "-fov2d")
     {
       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
       if (anArgValue != NULL
       && *anArgValue != '-')
       {
         ++anArgIter;
-        aCamera->SetFOVy (Draw::Atof (anArgValue));
+        if (anArgCase == "-fov2d")
+        {
+          aCamera->SetFOV2d (Draw::Atof (anArgValue));
+        }
+        else if (anArgCase == "-fovx")
+        {
+          aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
+        }
+        else
+        {
+          aCamera->SetFOVy (Draw::Atof (anArgValue));
+        }
         continue;
       }
-      theDI << aCamera->FOVy() << " ";
+      if (anArgCase == "-fov2d")
+      {
+        theDI << aCamera->FOV2d() << " ";
+      }
+      else if (anArgCase == "-fovx")
+      {
+        theDI << aCamera->FOVx() << " ";
+      }
+      else
+      {
+        theDI << aCamera->FOVy() << " ";
+      }
+    }
+    else if (anArgIter + 1 < theArgsNb
+          && anArgCase == "-xrpose")
+    {
+      TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
+      anXRArg.LowerCase();
+      if (anXRArg == "base")
+      {
+        aCamera = aView->View()->BaseXRCamera();
+      }
+      else if (anXRArg == "head")
+      {
+        aCamera = aView->View()->PosedXRCamera();
+      }
+      else
+      {
+        Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
+        return 1;
+      }
+      if (aCamera.IsNull())
+      {
+        Message::SendFail() << "Error: undefined XR pose";
+        return 0;
+      }
+      if (aView->AutoZFitMode())
+      {
+        const Bnd_Box aMinMaxBox  = aView->View()->MinMaxValues (false);
+        const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
+        aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
+      }
     }
     else if (aPrsName.IsEmpty()
          && !anArgCase.StartsWith ("-"))
@@ -10195,7 +10167,7 @@ static int VCamera (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Error: unknown argument '" << anArg << "'";
       return 1;
     }
   }
@@ -10203,7 +10175,6 @@ static int VCamera (Draw_Interpretor& theDI,
   if (aPrsName.IsEmpty()
    || theArgsNb > 2)
   {
-    aView->AutoZFit();
     aView->Redraw();
   }
 
@@ -10216,7 +10187,7 @@ static int VCamera (Draw_Interpretor& theDI,
       aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
       if (aCameraFrustum.IsNull())
       {
-        std::cout << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum!\n";
+        Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
         return 1;
       }
     }
@@ -10231,7 +10202,7 @@ static int VCamera (Draw_Interpretor& theDI,
       ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
       aView->ZFitAll();
     }
-    aCameraFrustum->SetCameraFrustum (aView->Camera());
+    aCameraFrustum->SetCameraFrustum (aCamera);
 
     ViewerTest::Display (aPrsName, aCameraFrustum);
   }
@@ -10284,6 +10255,11 @@ inline Standard_Boolean parseStereoMode (Standard_CString      theArg,
   {
     theMode = Graphic3d_StereoMode_SoftPageFlip;
   }
+  else if (aFlag == "openvr"
+        || aFlag == "vr")
+  {
+    theMode = Graphic3d_StereoMode_OpenVR;
+  }
   else
   {
     return Standard_False;
@@ -10341,7 +10317,7 @@ static int VStereo (Draw_Interpretor& theDI,
   {
     if (aView.IsNull())
     {
-      std::cout << "Error: no active viewer!\n";
+      Message::SendFail ("Error: no active viewer");
       return 0;
     }
 
@@ -10359,6 +10335,7 @@ static int VStereo (Draw_Interpretor& theDI,
         case Graphic3d_StereoMode_SideBySide       : aMode = "sideBySide";       break;
         case Graphic3d_StereoMode_OverUnder        : aMode = "overUnder";        break;
         case Graphic3d_StereoMode_SoftPageFlip     : aMode = "softpageflip";     break;
+        case Graphic3d_StereoMode_OpenVR           : aMode = "openVR";           break;
         case Graphic3d_StereoMode_Anaglyph  :
           aMode = "anaglyph";
           switch (aView->RenderingParams().AnaglyphFilter)
@@ -10402,7 +10379,7 @@ static int VStereo (Draw_Interpretor& theDI,
     {
       if (++anArgIter < theArgNb)
       {
-        std::cout << "Error: wrong number of arguments!\n";
+        Message::SendFail ("Error: wrong number of arguments");
         return 1;
       }
 
@@ -10419,7 +10396,7 @@ static int VStereo (Draw_Interpretor& theDI,
     {
       if (++anArgIter < theArgNb)
       {
-        std::cout << "Error: wrong number of arguments!\n";
+        Message::SendFail ("Error: wrong number of arguments");
         return 1;
       }
 
@@ -10428,7 +10405,10 @@ static int VStereo (Draw_Interpretor& theDI,
         aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
       }
       ViewerTest_myDefaultCaps.contextStereo = Standard_True;
-      return 0;
+      if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
+      {
+        return 0;
+      }
     }
     else if (aFlag == "-reverse"
           || aFlag == "-reversed"
@@ -10459,7 +10439,7 @@ static int VStereo (Draw_Interpretor& theDI,
       if (++anArgIter >= theArgNb
       || !parseStereoMode (theArgVec[anArgIter], aMode))
       {
-        std::cout << "Error: syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -10475,7 +10455,7 @@ static int VStereo (Draw_Interpretor& theDI,
       if (++anArgIter >= theArgNb
       || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
       {
-        std::cout << "Error: syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -10489,9 +10469,37 @@ static int VStereo (Draw_Interpretor& theDI,
         ViewerTest_myDefaultCaps.contextStereo = Standard_True;
       }
     }
+    else if (anArgIter + 1 < theArgNb
+          && aFlag == "-hmdfov2d")
+    {
+      aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
+      if (aParams->HmdFov2d < 10.0f
+       || aParams->HmdFov2d > 180.0f)
+      {
+        Message::SendFail() << "Error: FOV is out of range";
+        return 1;
+      }
+    }
+    else if (aFlag == "-mirror"
+          || aFlag == "-mirrorcomposer")
+    {
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+      && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aParams->ToMirrorComposer = toEnable;
+    }
+    else if (anArgIter + 1 < theArgNb
+          && (aFlag == "-unitfactor"
+           || aFlag == "-unitscale"))
+    {
+      aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
+    }
     else
     {
-      std::cout << "Error: syntax error at '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at '" << anArg << "'";
       return 1;
     }
   }
@@ -10500,6 +10508,11 @@ static int VStereo (Draw_Interpretor& theDI,
   {
     aParams->StereoMode = aMode;
     aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
+    if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
+    {
+      // initiate implicit continuous rendering
+      ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
+    }
   }
   return 0;
 }
@@ -10515,7 +10528,7 @@ static int VDefaults (Draw_Interpretor& theDi,
   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
   if (aCtx.IsNull())
   {
-    std::cout << "Error: no active viewer\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -10532,7 +10545,7 @@ static int VDefaults (Draw_Interpretor& theDi,
       theDi << "DeflType:           absolute\n"
             << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
     }
-    theDi << "AngularDeflection:  " << (180.0 * aDefParams->HLRAngle() / M_PI) << "\n";
+    theDi << "AngularDeflection:  " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
     theDi << "AutoTriangulation:  " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
     return 0;
   }
@@ -10548,7 +10561,7 @@ static int VDefaults (Draw_Interpretor& theDi,
     {
       if (++anArgIter >= theArgsNb)
       {
-        std::cout << "Error: wrong syntax at " << anArg << "\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       aDefParams->SetTypeOfDeflection         (Aspect_TOD_ABSOLUTE);
@@ -10562,7 +10575,7 @@ static int VDefaults (Draw_Interpretor& theDi,
     {
       if (++anArgIter >= theArgsNb)
       {
-        std::cout << "Error: wrong syntax at " << anArg << "\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
       aDefParams->SetTypeOfDeflection     (Aspect_TOD_RELATIVE);
@@ -10574,11 +10587,10 @@ static int VDefaults (Draw_Interpretor& theDi,
     {
       if (++anArgIter >= theArgsNb)
       {
-        std::cout << "Error: wrong syntax at " << anArg << "\n";
+        Message::SendFail() << "Syntax error at " << anArg;
         return 1;
       }
-      // currently HLRDeviationAngle is used instead of DeviationAngle in most places
-      aDefParams->SetHLRAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
+      aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
     }
     else if (anArg == "-AUTOTR"
           || anArg == "-AUTOTRIANG"
@@ -10589,14 +10601,14 @@ static int VDefaults (Draw_Interpretor& theDi,
       if (anArgIter >= theArgsNb
       || !ViewerTest::ParseOnOff (theArgVec[anArgIter], toTurnOn))
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
       aDefParams->SetAutoTriangulation (toTurnOn);
     }
     else
     {
-      std::cout << "Syntax error: unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
       return 1;
     }
   }
@@ -10668,7 +10680,7 @@ static int VLight (Draw_Interpretor& theDi,
   if (aView.IsNull()
    || aViewer.IsNull())
   {
-    std::cerr << "No active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -10713,6 +10725,7 @@ static int VLight (Draw_Interpretor& theDi,
           theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
           aLight->Attenuation (anAtten[0], anAtten[1]);
           theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
+          theDi << "  Range:      " << aLight->Range() << "\n";
           break;
         }
         case V3d_SPOT:
@@ -10728,6 +10741,7 @@ static int VLight (Draw_Interpretor& theDi,
           theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
           theDi << "  Angle:      " << (aLight->Angle() * 180.0 / M_PI) << "\n";
           theDi << "  Exponent:   " << aLight->Concentration() << "\n";
+          theDi << "  Range:      " << aLight->Range() << "\n";
           break;
         }
         default:
@@ -10773,7 +10787,7 @@ static int VLight (Draw_Interpretor& theDi,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -10808,7 +10822,7 @@ static int VLight (Draw_Interpretor& theDi,
       }
       else
       {
-        std::cout << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
     }
@@ -10874,7 +10888,7 @@ static int VLight (Draw_Interpretor& theDi,
     {
       if (!toCreate)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -10887,7 +10901,7 @@ static int VLight (Draw_Interpretor& theDi,
     {
       if (!toCreate)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -10900,7 +10914,7 @@ static int VLight (Draw_Interpretor& theDi,
     {
       if (!toCreate)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -10913,7 +10927,7 @@ static int VLight (Draw_Interpretor& theDi,
     {
       if (!toCreate)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -10926,7 +10940,7 @@ static int VLight (Draw_Interpretor& theDi,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -10945,7 +10959,7 @@ static int VLight (Draw_Interpretor& theDi,
 
       if (aLightOld.IsNull())
       {
-        std::cerr << "Light " << theArgVec[anArgIt] << " is undefined!\n";
+        Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
         return 1;
       }
     }
@@ -10957,7 +10971,7 @@ static int VLight (Draw_Interpretor& theDi,
       Handle(V3d_Light) aLightDel;
       if (++anArgIt >= theArgsNb)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11014,7 +11028,7 @@ static int VLight (Draw_Interpretor& theDi,
       if (++anArgIt >= theArgsNb
        || aLightCurr.IsNull())
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11033,7 +11047,7 @@ static int VLight (Draw_Interpretor& theDi,
        || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
         && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11052,7 +11066,7 @@ static int VLight (Draw_Interpretor& theDi,
        || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
         && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11069,7 +11083,7 @@ static int VLight (Draw_Interpretor& theDi,
       if (++anArgIt >= theArgsNb
        || aLightCurr.IsNull())
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11105,7 +11119,7 @@ static int VLight (Draw_Interpretor& theDi,
       if (++anArgIt >= theArgsNb
        || aLightCurr.IsNull())
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11121,7 +11135,7 @@ static int VLight (Draw_Interpretor& theDi,
        || aLightCurr.IsNull()
        || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11138,7 +11152,7 @@ static int VLight (Draw_Interpretor& theDi,
        || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
         && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11158,7 +11172,7 @@ static int VLight (Draw_Interpretor& theDi,
        || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
         && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11179,12 +11193,26 @@ static int VLight (Draw_Interpretor& theDi,
        || aLightCurr.IsNull()
        || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
     }
+    else if (anArgCase.IsEqual("RANGE")
+          || anArgCase.IsEqual("-RANGE"))
+    {
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull()
+       || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
+       || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
+      {
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
+        return 1;
+      }
+
+      aLightCurr->SetRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
+    }
     else if (anArgCase.IsEqual ("HEAD")
           || anArgCase.IsEqual ("HEADLIGHT")
           || anArgCase.IsEqual ("-HEAD")
@@ -11193,7 +11221,7 @@ static int VLight (Draw_Interpretor& theDi,
       if (aLightCurr.IsNull()
        || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11207,7 +11235,7 @@ static int VLight (Draw_Interpretor& theDi,
     }
     else
     {
-      std::cerr << "Warning: unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
     }
   }
 
@@ -11225,14 +11253,14 @@ static int VPBREnvironment (Draw_Interpretor&,
 {
   if (theArgsNb > 2)
   {
-    std::cerr << "Error: 'vpbrenv' command has only one argument\n";
+    Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
     return 1;
   }
 
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "Error: no active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -11250,7 +11278,7 @@ static int VPBREnvironment (Draw_Interpretor&,
   }
   else
   {
-    std::cerr << "Error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command\n";
+    Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
     return 1;
   }
 
@@ -11303,6 +11331,7 @@ static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theVa
         || aVal == "triangles")  aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
   else if (aVal == "pnts"
         || aVal == "points")     aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
+  else if (aVal == "lines")      aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
   else if (aVal == "mem"
         || aVal == "gpumem"
         || aVal == "estimmem")   aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
@@ -11383,7 +11412,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "Error: no active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -11417,13 +11446,13 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: unknown argument '" << theArgVec[1] << "'\n";
+        Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
         return 1;
       }
     }
     else
     {
-      std::cout << "Error: wrong number of arguments\n";
+      Message::SendFail ("Syntax error: wrong number of arguments");
       return 1;
     }
   }
@@ -11497,6 +11526,10 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       {
         theDI << " tris";
       }
+      if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
+      {
+        theDI << " lines";
+      }
       if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
       {
         theDI << " pnts";
@@ -11560,7 +11593,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
     }
@@ -11596,14 +11629,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
       if (aNbSamples < 0)
       {
-        std::cerr << "Error: invalid number of MSAA samples " << aNbSamples << ".\n";
+        Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
         return 1;
       }
       else
@@ -11622,7 +11655,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11630,7 +11663,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
       if (aFeather <= 0.0f)
       {
-        std::cerr << "Error: invalid value of line width feather " << aFeather << ". Should be > 0\n";
+        Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
         return 1;
       }
       aParams.LineFeather = aFeather;
@@ -11651,7 +11684,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11662,7 +11695,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
         const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
         if (aWeight < 0.f || aWeight > 1.f)
         {
-          std::cerr << "Error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]\n";
+          Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
           return 1;
         }
 
@@ -11675,7 +11708,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
     }
@@ -11719,14 +11752,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
       if (aScale < 0.01)
       {
-        std::cerr << "Error: invalid rendering resolution scale " << aScale << ".\n";
+        Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
         return 1;
       }
       else
@@ -11744,7 +11777,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -11753,7 +11786,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       // We allow RaytracingDepth be more than 10 in case of GI enabled
       if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
       {
-        std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
+        Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
         return 1;
       }
       else
@@ -11873,21 +11906,21 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
       if (!aMaxRadStr.IsRealValue())
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
       if (aMaxRadiance <= 0.0)
       {
-        std::cerr << "Error: invalid radiance clamping value " << aMaxRadiance << ".\n";
+        Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
         return 1;
       }
       else
@@ -11952,14 +11985,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
       if (aTileSize < 1)
       {
-        std::cerr << "Error: invalid size of ISS tile " << aTileSize << ".\n";
+        Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
         return 1;
       }
       aParams.RayTracingTileSize = aTileSize;
@@ -11973,21 +12006,21 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
       if (aNbTiles < -1)
       {
-        std::cerr << "Error: invalid number of ISS tiles " << aNbTiles << ".\n";
+        Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
         return 1;
       }
       else if (aNbTiles > 0
             && (aNbTiles < 64
              || aNbTiles > 1024))
       {
-        std::cerr << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].\n";
+        Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
       }
       aParams.NbRayTracingTiles = aNbTiles;
     }
@@ -12007,6 +12040,22 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       aParams.UseEnvironmentMapBackground = toEnable;
     }
+    else if (aFlag == "-ignorenormalmap")
+    {
+      if (toPrint)
+      {
+        theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
+        continue;
+      }
+
+      Standard_Boolean toEnable = Standard_True;
+      if (++anArgIter < theArgNb
+        && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
+      {
+        --anArgIter;
+      }
+      aParams.ToIgnoreNormalMapInRayTracing = toEnable;
+    }
     else if (aFlag == "-twoside")
     {
       if (toPrint)
@@ -12044,7 +12093,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
 
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
       }
 
       Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
@@ -12055,7 +12104,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: unknown shading model '" << theArgVec[anArgIter] << "'\n";
+        Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
         return 1;
       }
     }
@@ -12065,14 +12114,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
       if (aPbrEnvPow2Size < 1)
       {
-        std::cout << "Error: 'Pow2Size' of PBR Environment has to be greater or equal 1\n";
+        Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
         return 1;
       }
       aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
@@ -12085,14 +12134,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
       if (aPbrEnvSpecMapNbLevels < 2)
       {
-        std::cout << "Error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2\n";
+        Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
         return 1;
       }
       aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
@@ -12103,14 +12152,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
       const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
       if (aPbrEnvBakingDiffNbSamples < 1)
       {
-        std::cout << "Error: 'BakingDiffSamplesNumber' of PBR Environtment has to be greater or equal 1\n";
+        Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environtment has to be greater or equal 1");
         return 1;
       }
       aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
@@ -12121,14 +12170,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
     if (++anArgIter >= theArgNb)
     {
-      std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error at argument '" << anArg << "'";
       return 1;
     }
 
     const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
     if (aPbrEnvBakingSpecNbSamples < 1)
     {
-      std::cout << "Error: 'BakingSpecSamplesNumber' of PBR Environtment has to be greater or equal 1\n";
+      Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environtment has to be greater or equal 1");
       return 1;
     }
     aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
@@ -12138,14 +12187,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
       if (aPbrEnvBakingProbability < 0.f
        || aPbrEnvBakingProbability > 1.f)
       {
-        std::cout << "Error: 'BakingProbability' of PBR Environtment has to be in range of [0, 1]\n";
+        Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environtment has to be in range of [0, 1]");
         return 1;
       }
       aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
@@ -12154,7 +12203,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12165,7 +12214,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
         return 1;
       }
     }
@@ -12190,7 +12239,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12200,14 +12249,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
         float aFocalDist = static_cast<float> (aParam.RealValue());
         if (aFocalDist < 0)
         {
-          std::cout << "Error: parameter can't be negative at argument '" << anArg << "'.\n";
+          Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
           return 1;
         }
         aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
       }
       else
       {
-        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        Message::SendFail() << "Syntax error at argument'" << anArg << "'";
         return 1;
       }
     }
@@ -12215,7 +12264,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12225,14 +12274,14 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
         float aApertureSize = static_cast<float> (aParam.RealValue());
         if (aApertureSize < 0)
         {
-          std::cout << "Error: parameter can't be negative at argument '" << anArg << "'.\n";
+          Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
           return 1;
         }
         aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
       }
       else
       {
-        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        Message::SendFail() << "Syntax error at argument'" << anArg << "'";
         return 1;
       }
     }
@@ -12240,7 +12289,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12251,7 +12300,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        Message::SendFail() << "Syntax error at argument'" << anArg << "'";
         return 1;
       }
     }
@@ -12259,7 +12308,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12270,7 +12319,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        Message::SendFail() << "Syntax error at argument'" << anArg << "'";
         return 1;
       }
     }
@@ -12278,7 +12327,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12295,7 +12344,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+        Message::SendFail() << "Syntax error at argument'" << anArg << "'";
         return 1;
       }
     }
@@ -12307,7 +12356,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
 
@@ -12316,7 +12365,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
       Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
       if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       aView->ChangeRenderingParams().CollectedStats = aFlags;
@@ -12327,7 +12376,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
@@ -12337,7 +12386,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
@@ -12347,7 +12396,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     {
       if (++anArgIter >= theArgNb)
       {
-        std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at argument '" << anArg << "'";
         return 1;
       }
       aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
@@ -12387,7 +12436,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
       return 1;
     }
   }
@@ -12423,7 +12472,7 @@ static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
   Handle(V3d_View) aView = ViewerTest::CurrentView();
   if (aView.IsNull())
   {
-    std::cerr << "Error: no active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -12448,7 +12497,9 @@ static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
       else if (aFlag == "alllayers"
             || aFlag == "layers")     aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
       else if (aFlag == "allstructs"
-            || aFlag == "structs")    aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
+            || aFlag == "allstructures"
+            || aFlag == "structs"
+            || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
       else if (aFlag == "groups")     aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
       else if (aFlag == "allarrays"
             || aFlag == "fillarrays"
@@ -12456,6 +12507,7 @@ static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
             || aFlag == "pointarrays"
             || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
       else if (aFlag == "triangles")  aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
+      else if (aFlag == "lines")      aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
       else if (aFlag == "points")     aParam = Graphic3d_RenderingParams::PerfCounters_Points;
       else if (aFlag == "geommem"
             || aFlag == "texturemem"
@@ -12471,7 +12523,7 @@ static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
             || aFlag == "cpudynmax")  aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
       else
       {
-        std::cerr << "Unknown argument '" << theArgVec[anArgIter] << "'!\n";
+        Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
         continue;
       }
 
@@ -12517,13 +12569,20 @@ static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
       {
         theDI << searchInfo (aDict, "Rendered layers") << " ";
       }
-      else if (aFlag == "allstructs")
+      else if (aFlag == "allstructs"
+            || aFlag == "allstructures")
       {
         theDI << searchInfo (aDict, "Structs") << " ";
       }
-      else if (aFlag == "structs")
+      else if (aFlag == "structs"
+            || aFlag == "structures")
       {
-        theDI << searchInfo (aDict, "Rendered structs") << " ";
+        TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
+        if (aRend.IsEmpty()) // all structures rendered
+        {
+          aRend = searchInfo (aDict, "Structs");
+        }
+        theDI << aRend << " ";
       }
       else if (aFlag == "groups")
       {
@@ -12676,7 +12735,7 @@ static int VManipulator (Draw_Interpretor& theDi,
   if (aCurrentView.IsNull()
    || aViewer.IsNull())
   {
-    std::cerr << "No active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -12729,7 +12788,7 @@ static int VManipulator (Draw_Interpretor& theDi,
 
   if (aName.IsEmpty())
   {
-    std::cerr << theArgVec[0] << " error: please specify AIS manipulator's name as the first argument.\n";
+    Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
     return 1;
   }
 
@@ -12741,14 +12800,14 @@ static int VManipulator (Draw_Interpretor& theDi,
   {
     if (!aMapAIS.IsBound2 (aName))
     {
-      std::cerr << theArgVec[0] << " error: could not find \"" << aName << "\" AIS object.\n";
+      Message::SendFail() << "Syntax error: could not find \"" << aName << "\" AIS object";
       return 1;
     }
 
     Handle(AIS_Manipulator) aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
     if (aManipulator.IsNull())
     {
-      std::cerr << theArgVec[0] << " error: \"" << aName << "\" is not an AIS manipulator.\n";
+      Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
       return 1;
     }
 
@@ -12777,7 +12836,7 @@ static int VManipulator (Draw_Interpretor& theDi,
     aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
     if (aManipulator.IsNull())
     {
-      std::cerr << theArgVec[0] << " error: \"" << aName << "\" is not an AIS manipulator.\n";
+      Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
       return 1;
     }
   }
@@ -12813,7 +12872,7 @@ static int VManipulator (Draw_Interpretor& theDi,
     Standard_Boolean aOnOff = aCmd.ArgBool ("part", 2);
     if (aMode < 1 || aMode > 4)
     {
-      std::cerr << theArgVec[0] << " error: mode value should be in range [1, 4].\n";
+      Message::SendFail ("Syntax error: mode value should be in range [1, 4]");
       return 1;
     }
 
@@ -12825,7 +12884,7 @@ static int VManipulator (Draw_Interpretor& theDi,
     Standard_Boolean aOnOff = aCmd.ArgBool("parts", 1);
     if (aMode < 1 || aMode > 4)
     {
-      std::cerr << theArgVec[0] << " error: mode value should be in range [1, 4].\n";
+      Message::SendFail ("Syntax error: mode value should be in range [1, 4]");
       return 1;
     }
 
@@ -12870,7 +12929,7 @@ static int VManipulator (Draw_Interpretor& theDi,
     Handle(AIS_InteractiveObject) anObject;
     if (!aMapAIS.Find2 (anObjName, anObject))
     {
-      std::cerr << theArgVec[0] << " error: AIS object \"" << anObjName << "\" does not exist.\n";
+      Message::SendFail() << "Syntax error: AIS object \"" << anObjName << "\" does not exist";
       return 1;
     }
 
@@ -12882,7 +12941,7 @@ static int VManipulator (Draw_Interpretor& theDi,
        && aManip->IsAttached()
        && aManip->Object() == anObject)
       {
-        std::cerr << theArgVec[0] << " error: AIS object \"" << anObjName << "\" already has manipulator.\n";
+        Message::SendFail() << "Syntax error: AIS object \"" << anObjName << "\" already has manipulator";
         return 1;
       }
     }
@@ -12921,13 +12980,13 @@ static int VManipulator (Draw_Interpretor& theDi,
         ViewerTest_Names aViewNames (aViewString);
         if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
         {
-          std::cerr << theArgVec[0] << " error: wrong view name '" << aViewString << "'\n";
+          Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
           return 1;
         }
         aView = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
         if (aView.IsNull())
         {
-          std::cerr << theArgVec[0] << " error: cannot find view with name '" << aViewString << "'\n";
+          Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
           return 1;
         }
       }
@@ -12994,7 +13053,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
   if (aCtx.IsNull())
   {
-    std::cerr << "No active viewer!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -13010,7 +13069,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
     else if (theArgsNb != 2
          || !ViewerTest::ParseOnOff (theArgVec[1], toEnable))
     {
-      std::cout << "Syntax error: wrong number of parameters.";
+      Message::SendFail ("Syntax error: wrong number of parameters");
       return 1;
     }
     if (toEnable != aCtx->ToHilightSelected())
@@ -13120,7 +13179,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
     {
       if (++anArgIter >= theArgsNb)
       {
-        std::cout << "Syntax error: type of highlighting is undefined\n";
+        Message::SendFail ("Syntax error: type of highlighting is undefined");
         return 1;
       }
 
@@ -13140,7 +13199,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
       }
       else
       {
-        std::cout << "Syntax error: unknwon picking strategy '" << aVal << "'\n";
+        Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
         return 1;
       }
 
@@ -13157,7 +13216,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
     {
       if (aType == Prs3d_TypeOfHighlight_None)
       {
-        std::cout << "Syntax error: type of highlighting is undefined\n";
+        Message::SendFail ("Syntax error: type of highlighting is undefined");
         return 1;
       }
 
@@ -13171,7 +13230,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
     {
       if (aType == Prs3d_TypeOfHighlight_None)
       {
-        std::cout << "Syntax error: type of highlighting is undefined\n";
+        Message::SendFail ("Syntax error: type of highlighting is undefined");
         return 1;
       }
 
@@ -13179,7 +13238,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
       Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
       if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
       {
-        std::cerr << "Error: wrong syntax at " << theArgVec[anArgIter] << ".\n";
+        Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
         return 1;
       }
 
@@ -13201,7 +13260,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
       }
       else if (aType == Prs3d_TypeOfHighlight_None)
       {
-        std::cout << "Syntax error: type of highlighting is undefined\n";
+        Message::SendFail ("Syntax error: type of highlighting is undefined");
         return 1;
       }
 
@@ -13211,7 +13270,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
                                                            aColor);
       if (aNbParsed == 0)
       {
-        std::cout << "Syntax error: need more arguments.\n";
+        Message::SendFail ("Syntax error: need more arguments");
         return 1;
       }
       anArgIter += aNbParsed;
@@ -13238,7 +13297,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
       }
       else if (aType == Prs3d_TypeOfHighlight_None)
       {
-        std::cout << "Syntax error: type of highlighting is undefined\n";
+        Message::SendFail ("Syntax error: type of highlighting is undefined");
         return 1;
       }
 
@@ -13253,7 +13312,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
     {
       if (aType == Prs3d_TypeOfHighlight_None)
       {
-        std::cout << "Syntax error: type of highlighting is undefined\n";
+        Message::SendFail ("Syntax error: type of highlighting is undefined");
         return 1;
       }
 
@@ -13279,7 +13338,7 @@ static int VSelectionProperties (Draw_Interpretor& theDi,
     }
     else
     {
-      std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+      Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
     }
   }
 
@@ -13319,19 +13378,21 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
 {
   if (theArgsNb < 2)
   {
-    std::cout << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'\n";
+    Message::SendFail() << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'";
     return 1;
   }
 
   const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
+  const Handle(V3d_View)& aView = ViewerTest::CurrentView();
   if (aContext.IsNull())
   {
-    std::cout << "Error: no active view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
   TCollection_AsciiString aFile;
   StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
+  Handle(Graphic3d_Camera) aCustomCam;
   Image_Format anImgFormat = Image_Format_BGR;
   Standard_Integer aPickedIndex = 1;
   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
@@ -13342,7 +13403,7 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
     {
       if (++anArgIter >= theArgsNb)
       {
-        std::cout << "Syntax error: wrong number parameters of flag '-depth'.\n";
+        Message::SendFail ("Syntax error: wrong number parameters of flag '-depth'");
         return 1;
       }
 
@@ -13399,46 +13460,82 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
     {
       if (++anArgIter >= theArgsNb)
       {
-        std::cout << "Syntax error: wrong number parameters at '" << aParam << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
         return 1;
       }
 
       aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
     }
+    else if (anArgIter + 1 < theArgsNb
+          && aParam == "-xrpose")
+    {
+      TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
+      anXRArg.LowerCase();
+      if (anXRArg == "base")
+      {
+        aCustomCam = aView->View()->BaseXRCamera();
+      }
+      else if (anXRArg == "head")
+      {
+        aCustomCam = aView->View()->PosedXRCamera();
+      }
+      else
+      {
+        Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
+        return 1;
+      }
+      if (aCustomCam.IsNull())
+      {
+        Message::SendFail() << "Error: undefined XR pose";
+        return 0;
+      }
+    }
     else if (aFile.IsEmpty())
     {
       aFile = theArgVec[anArgIter];
     }
     else
     {
-      std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'.\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
       return 1;
     }
   }
   if (aFile.IsEmpty())
   {
-    std::cout << "Syntax error: image file name is missing.\n";
+    Message::SendFail ("Syntax error: image file name is missing");
     return 1;
   }
 
-  const Handle(V3d_View)& aView = ViewerTest::CurrentView();
   Standard_Integer aWidth = 0, aHeight = 0;
   aView->Window()->Size (aWidth, aHeight);
 
   Image_AlienPixMap aPixMap;
   if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
   {
-    std::cout << "Error: can't allocate image.\n";
+    Message::SendFail ("Error: can't allocate image");
     return 1;
   }
+
+  const bool wasImmUpdate = aView->SetImmediateUpdate (false);
+  Handle(Graphic3d_Camera) aCamBack = aView->Camera();
+  if (!aCustomCam.IsNull())
+  {
+    aView->SetCamera (aCustomCam);
+  }
   if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
   {
-    std::cout << "Error: can't generate selection image.\n";
+    Message::SendFail ("Error: can't generate selection image");
     return 1;
   }
+  if (!aCustomCam.IsNull())
+  {
+    aView->SetCamera (aCamBack);
+  }
+  aView->SetImmediateUpdate (wasImmUpdate);
+
   if (!aPixMap.Save (aFile))
   {
-    std::cout << "Error: can't save selection image.\n";
+    Message::SendFail ("Error: can't save selection image");
     return 0;
   }
   return 0;
@@ -13456,12 +13553,12 @@ static int VViewCube (Draw_Interpretor& ,
   const Handle(V3d_View)& aView = ViewerTest::CurrentView();
   if (aContext.IsNull() || aView.IsNull())
   {
-    std::cout << "Error: no active view.\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   else if (theNbArgs < 2)
   {
-    std::cout << "Syntax error: wrong number arguments\n";
+    Message::SendFail ("Syntax error: wrong number arguments");
     return 1;
   }
 
@@ -13482,7 +13579,7 @@ static int VViewCube (Draw_Interpretor& ,
       aName = theArgVec[anArgIter];
       if (aName.StartsWith ("-"))
       {
-        std::cout << "Syntax error: object name should be specified.\n";
+        Message::SendFail ("Syntax error: object name should be specified");
         return 1;
       }
       Handle(AIS_InteractiveObject) aPrs;
@@ -13516,7 +13613,7 @@ static int VViewCube (Draw_Interpretor& ,
                                                            aColorRgb);
       if (aNbParsed == 0)
       {
-        std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
       anArgIter += aNbParsed;
@@ -13562,7 +13659,7 @@ static int VViewCube (Draw_Interpretor& ,
       const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
       if (aValue < 0.0 || aValue > 1.0)
       {
-        std::cout << "Syntax error: invalid transparency value " << theArgVec[anArgIter] << "\n";
+        Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
         return 1;
       }
 
@@ -13680,15 +13777,30 @@ static int VViewCube (Draw_Interpretor& ,
     {
       aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
     }
+    else if (anArgIter + 1 < theNbArgs
+          && anArg == "-axesradius")
+    {
+      aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
+    }
+    else if (anArgIter + 1 < theNbArgs
+          && anArg == "-axesconeradius")
+    {
+      aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
+    }
+    else if (anArgIter + 1 < theNbArgs
+          && anArg == "-axessphereradius")
+    {
+      aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
+    }
     else
     {
-      std::cout << "Syntax error: unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
       return 1;
     }
   }
   if (aViewCube.IsNull())
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -13696,6 +13808,91 @@ static int VViewCube (Draw_Interpretor& ,
   return 0;
 }
 
+//===============================================================================================
+//function : VColorConvert
+//purpose  :
+//===============================================================================================
+static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer  theNbArgs, const char** theArgVec)
+{
+  if (theNbArgs != 6)
+  {
+    std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
+    return 1;
+  }
+
+  Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
+  if (! convertFrom && strcasecmp (theArgVec[1], "to"))
+  {
+    std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
+    return 1;
+  }
+
+  const char* aTypeStr = theArgVec[2];
+  Quantity_TypeOfColor aType = Quantity_TOC_RGB;
+  if (! strcasecmp (aTypeStr, "srgb"))
+  {
+    aType = Quantity_TOC_sRGB;
+  }
+  else if (! strcasecmp (aTypeStr, "hls"))
+  {
+    aType = Quantity_TOC_HLS;
+  }
+  else if (! strcasecmp (aTypeStr, "lab"))
+  {
+    aType = Quantity_TOC_CIELab;
+  }
+  else if (! strcasecmp (aTypeStr, "lch"))
+  {
+    aType = Quantity_TOC_CIELch;
+  }
+  else
+  {
+    std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
+    return 1;
+  }
+
+  double aC1 = Draw::Atof (theArgVec[3]);
+  double aC2 = Draw::Atof (theArgVec[4]);
+  double aC3 = Draw::Atof (theArgVec[5]);
+
+  Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
+  aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
+
+  // print values with 6 decimal digits
+  char buffer[1024];
+  Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
+  theDI << buffer;
+
+  return 0;
+}
+//===============================================================================================
+//function : VColorDiff
+//purpose  :
+//===============================================================================================
+static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer  theNbArgs, const char** theArgVec)
+{
+  if (theNbArgs != 7)
+  {
+    std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
+    return 1;
+  }
+
+  double aR1 = Draw::Atof (theArgVec[1]);
+  double aG1 = Draw::Atof (theArgVec[2]);
+  double aB1 = Draw::Atof (theArgVec[3]);
+  double aR2 = Draw::Atof (theArgVec[4]);
+  double aG2 = Draw::Atof (theArgVec[5]);
+  double aB2 = Draw::Atof (theArgVec[6]);
+
+  Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
+  Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
+
+  theDI << aColor1.DeltaE2000 (aColor2);
+
+  return 0;
+}
 //=======================================================================
 //function : ViewerCommands
 //purpose  :
@@ -13938,9 +14135,11 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:       [-labels Label1 Label2 ...] [-label Index Label]"
     "\n\t\t:       [-freeLabels NbOfLabels Label1 Label2 ...]"
     "\n\t\t:       [-xy Left=0 Bottom=0]"
+    "\n\t\t:       [-uniform lightness hue_from hue_to]"
     "\n\t\t:  -demo     - displays a color scale with demonstratio values"
     "\n\t\t:  -colors   - set colors for all intervals"
     "\n\t\t:  -color    - set color for specific interval"
+    "\n\t\t:  -uniform  - generate colors with the same lightness"
     "\n\t\t:  -textpos  - horizontal label position relative to color scale bar"
     "\n\t\t:  -labelAtBorder - vertical label position relative to color interval;"
     "\n\t\t:              at border means the value inbetween neighbor intervals,"
@@ -13952,7 +14151,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:  -title    - set title"
     "\n\t\t:  -reversed - setup smooth color transition between intervals"
     "\n\t\t:  -smoothTransition - swap colorscale direction"
-    "\n\t\t:  -hueRange - set hue angles corresponding to minimum and maximum values"
+    "\n\t\t:  -hueRange - set hue angles corresponding to minimum and maximum values",
     __FILE__, VColorScale, group);
   theCommands.Add("vgraduatedtrihedron",
     "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
@@ -14058,8 +14257,12 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     __FILE__, VVbo, group);
   theCommands.Add ("vstereo",
             "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
+    "\n\t\t:         [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
     "\n\t\t:         [-anaglyph Filter]"
-    "\n\t\t: Control stereo output mode. Available modes for -mode:"
+    "\n\t\t: Control stereo output mode."
+    "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
+    "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
+    "\n\t\t: Available modes for -mode:"
     "\n\t\t:  quadBuffer        - OpenGL QuadBuffer stereo,"
     "\n\t\t:                     requires driver support."
     "\n\t\t:                     Should be called BEFORE vinit!"
@@ -14069,13 +14272,14 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:  chessBoard       - chess-board output"
     "\n\t\t:  sideBySide       - horizontal pair"
     "\n\t\t:  overUnder        - vertical   pair"
+    "\n\t\t:  openVR           - OpenVR (HMD)"
     "\n\t\t: Available Anaglyph filters for -anaglyph:"
     "\n\t\t:  redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
     "\n\t\t:  greenMagentaSimple",
     __FILE__, VStereo, group);
   theCommands.Add ("vcaps",
             "vcaps [-sRGB {0|1}] [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]"
-    "\n\t\t:       [-compatibleProfile {0|1}]"
+    "\n\t\t:       [-compatibleProfile {0|1}] [-compressedTextures {0|1}]"
     "\n\t\t:       [-vsync {0|1}] [-useWinBuffer {0|1}]"
     "\n\t\t:       [-quadBuffer {0|1}] [-stereo {0|1}]"
     "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
@@ -14086,6 +14290,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:             built-in GLSL programs"
     "\n\t\t:            (requires compatible profile)"
     "\n\t\t:  polygonMode - use Polygon Mode instead of built-in GLSL programs"
+    "\n\t\t:  compressedTexture - allow uploading of GPU-supported compressed texture formats"
     "\n\t\t:  VBO      - use Vertex Buffer Object (copy vertex"
     "\n\t\t:             arrays to GPU memory)"
     "\n\t\t:  sprite   - use textured sprites instead of bitmaps"
@@ -14124,10 +14329,10 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "- 1) single click selection\n"
     "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
     "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
-    "- 4) -allowoverlap manages overlap and inclusion detection in rectangular selection.\n"
-    "     If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined rectangle will be detected,\n"
-    "     otherwise algorithm will chose only fully included sensitives. Default behavior is to detect only full inclusion. "
-    " (partial inclusion - overlap - is not allowed by default)\n"
+    "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
+    "     If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
+    "     rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
+    "     Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
     "- 5) any of these selections with shift button pressed",
     __FILE__, VSelect, group);
   theCommands.Add ("vmoveto",
@@ -14237,6 +14442,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
       "\n\t\t:         [-stereo] [-leftEye] [-rightEye]"
       "\n\t\t:         [-iod [Distance]] [-iodType    [absolute|relative]]"
       "\n\t\t:         [-zfocus [Value]] [-zfocusType [absolute|relative]]"
+      "\n\t\t:         [-fov2d  [Angle]] [-lockZup {0|1}]"
+      "\n\t\t:         [-xrPose base|head=base]"
       "\n\t\t: Manages camera parameters."
       "\n\t\t: Displays frustum when presntation name PrsName is specified."
       "\n\t\t: Prints current value when option called without argument."
@@ -14245,7 +14452,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
       "\n\t\t: Perspective camera:"
       "\n\t\t:   -persp      activate perspective  projection (mono)"
       "\n\t\t:   -fovy       field of view in y axis, in degrees"
+      "\n\t\t:   -fov2d      field of view limit for 2d on-screen elements"
       "\n\t\t:   -distance   distance of eye from camera center"
+      "\n\t\t:   -lockZup    lock Z up (tunrtable mode)"
       "\n\t\t: Stereoscopic camera:"
       "\n\t\t:   -stereo     perspective  projection (stereo)"
       "\n\t\t:   -leftEye    perspective  projection (left  eye)"
@@ -14368,6 +14577,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n        -{linearAtten}uation value"
     "\n        -angle angleDeg"
     "\n        -{spotexp}onent value"
+    "\n        -range value"
     "\n        -local|-global"
     "\n\n        example: vlight -add positional -head 1 -pos 0 1 1 -color red"
     "\n        example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
@@ -14402,6 +14612,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n      '-gi           on|off'      Enables/disables global illumination effects"
     "\n      '-brng         on|off'      Enables/disables blocked RNG (fast coherent PT)"
     "\n      '-env          on|off'      Enables/disables environment map background"
+    "\n      '-ignoreNormalMap on|off'   Enables/disables normal map ignoring during path tracing"
     "\n      '-twoside      on|off'      Enables/disables two-sided BSDF models (PT mode)"
     "\n      '-iss          on|off'      Enables/disables adaptive screen sampling (PT mode)"
     "\n      '-issd         on|off'      Shows screen sampling distribution in ISS mode"
@@ -14422,7 +14633,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n      '-exposure     value'       Exposure value for tone mapping (0.0 value disables the effect)"
     "\n      '-whitepoint   value'       White point value for filmic tone mapping"
     "\n      '-tonemapping  mode'        Tone mapping mode (disabled, filmic)"
-    "\n      '-perfCounters none|fps|cpu|layers|structures|groups|arrays|triagles|points"
+    "\n      '-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
     "\n      '              |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate'"
     "\n                                  Show/hide performance counters (flags can be combined)"
     "\n      '-perfUpdateInterval nbSeconds' Performance counters update interval"
@@ -14437,7 +14648,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
   theCommands.Add("vstatprofiler",
     "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
     "\n                |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
-    "\n                |triagles|points|geomMem|textureMem|frameMem"
+    "\n                |triangles|points|geomMem|textureMem|frameMem"
     "\n                |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
     "\n                |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
     "\n                [-noredraw]"
@@ -14506,6 +14717,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
 
   theCommands.Add ("vseldump",
                    "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
+                   "\n\t\t:       [-xrPose base|head=base]"
                    "\n\t\t: Generate an image based on detection results:"
                    "\n\t\t:   depth       normalized depth values"
                    "\n\t\t:   unnormDepth unnormalized depth values"
@@ -14543,8 +14755,20 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
                    "\n\t\t:   -boxCornerMinSize Value  minimal box corner size"
                    "\n\t\t:   -axesPadding Value       padding between box and arrows"
                    "\n\t\t:   -roundRadius Value       relative radius of corners of sides within [0.0, 0.5] range"
+                   "\n\t\t:   -axesRadius Value        radius of axes of the trihedron"
+                   "\n\t\t:   -axesConeRadius Value    radius of the cone (arrow) of the trihedron"
+                   "\n\t\t:   -axesSphereRadius Value  radius of the sphere (central point) of trihedron"
                    "\n\t\t:   -fixedanimation {0|1}    uninterruptible animation loop"
                    "\n\t\t:   -duration Seconds        animation duration in seconds",
     __FILE__, VViewCube, group);
 
+  theCommands.Add("vcolorconvert" ,
+                  "vcolorconvert {from|to} type C1 C2 C2"
+                  "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
+                  "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
+                  "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
+                  __FILE__,VColorConvert,group);
+  theCommands.Add("vcolordiff" ,
+                  "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
+                  __FILE__,VColorDiff,group);
 }