0023432: Connected Interactive Objects computed without Interactive Context
[occt.git] / src / ViewerTest / ViewerTest_ObjectCommands.cxx
index 37334eb..ceea781 100755 (executable)
 #include <SelectMgr_Selection.hxx>
 #include <StdFail_NotDone.hxx>
 #include <StdPrs_ShadedShape.hxx>
-#include <TopoDS_Wire.hxx> 
+#include <TopoDS_Wire.hxx>
 
 #include <AIS_ConnectedShape.hxx>
+#include <AIS_MultipleConnectedInteractive.hxx>
+#include <AIS_MultipleConnectedShape.hxx>
 #include <TopLoc_Location.hxx>
 #include <TColStd_ListOfInteger.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <BRepExtrema_ExtPC.hxx>
 #include <BRepExtrema_ExtPF.hxx>
 
+#include <Prs3d_LineAspect.hxx>
+
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
 #endif
@@ -2299,7 +2303,7 @@ public:
       Standard_Real Angle ,
       Standard_Boolean Zoom ,
       Standard_Real  Height,
-      OSD_FontAspect FontAspect,
+      Font_FontAspect FontAspect,
       Standard_CString Font
     );
 
@@ -2323,7 +2327,7 @@ protected:
   Standard_Boolean                    aZoomable;
   Quantity_Color                      aColor;
   Standard_CString                    aFont;
-  OSD_FontAspect                      aFontAspect;
+  Font_FontAspect                     aFontAspect;
   Graphic3d_HorizontalTextAlignment   aHJustification;
   Graphic3d_VerticalTextAlignment     aVJustification;
 };
@@ -2341,7 +2345,7 @@ MyTextClass::MyTextClass( const TCollection_ExtendedString& text, const gp_Pnt&
                           Standard_Real     angle       = 0.0 ,
                           Standard_Boolean  zoomable    = Standard_True,
                           Standard_Real     height      = 12.,
-                          OSD_FontAspect    fontAspect  = OSD_FA_Regular,
+                          Font_FontAspect   fontAspect  = Font_FA_Regular,
                           Standard_CString  font        = "Courier")
 {
   aText           = text;
@@ -2441,7 +2445,7 @@ static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char**
   const Standard_Real height = atof(argv[12]);
 
   // Text aspect
-  const OSD_FontAspect aspect = OSD_FontAspect(atoi(argv[13]));
+  const Font_FontAspect aspect = Font_FontAspect(atoi(argv[13]));
 
   // Text font
   TCollection_AsciiString font;
@@ -3251,10 +3255,10 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
   else if (argc < 3)
   {
-    di << "Use: " << argv[0] << " Name TypeOfArray [EnableVBO={0 | 1}]"
+    di << "Use: " << argv[0] << " Name TypeOfArray"
        << " [vertex] ... [bounds] ... [edges]\n"
        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
-       << "                trianglefan | trianglestrips | quads |\n"
+       << "                trianglefans | trianglestrips | quads |\n"
        << "                quadstrips | polygons }\n"
        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
        << " [texel={ 't' tx ty }] } \n"
@@ -3264,20 +3268,16 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
 
   // read the arguments
-  TCollection_AsciiString aName (argv[1]);
-  TCollection_AsciiString anArrayType (argv[2]);
-  
-  // is argument list has an vbo flag
-  Standard_Boolean hasFlagVbo = Standard_False;
-  if (isdigit (argv[3][0]) && atoi (argv[3]) >= 0 && atoi (argv[3]) <= 1)
-    hasFlagVbo = Standard_True;
+  Standard_Integer aArgIndex = 1;
+  TCollection_AsciiString aName (argv[aArgIndex++]);
+  TCollection_AsciiString anArrayType (argv[aArgIndex++]);
+  const Standard_Integer anArgsFrom = aArgIndex;
 
   // parse number of verticies, bounds, edges
   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
   Standard_Boolean hasVColors, hasBColors, hasNormals, hasInfos, hasTexels;
   hasVColors = hasNormals = hasBColors = hasInfos = hasTexels = Standard_False;
 
-  Standard_Integer aArgIndex = (hasFlagVbo) ? 4 : 3;
   TCollection_AsciiString aCommand;
   while (aArgIndex < argc)
   {
@@ -3375,7 +3375,7 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
 
   // parse an array of primitives
-  aArgIndex = (hasFlagVbo) ? 4 : 3;
+  aArgIndex = anArgsFrom;
   while (aArgIndex < argc)
   {
     aCommand = argv[aArgIndex];
@@ -3438,17 +3438,6 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
       aArgIndex++;
   }
 
-  if (hasFlagVbo)
-  {
-    // enable / disable vbo
-    Handle(Graphic3d_GraphicDriver) aDriver =
-      Handle(Graphic3d_GraphicDriver)::DownCast (
-                      aContextAIS->CurrentViewer()->Device()->GraphicDriver());
-
-    if (!aDriver.IsNull())
-      aDriver->EnableVBO ((Standard_Boolean) atoi (argv[3]));
-  }
-
   // create primitives array object
   Handle (MyPArrayObject) aPObject = new MyPArrayObject (anArray);
 
@@ -3517,50 +3506,138 @@ static Standard_Integer VSetLocation (Draw_Interpretor& di,
 //===============================================================================================
 //function : VConnect
 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
-//Draw arg : vconnect name object Xo Yo Zo Xu Xv Xw Zu Zv Zw
+//Draw arg : vconnect name Xo Yo Zo Xu Xv Xw Zu Zv Zw object1 object2 ... [color=NAME]
 //===============================================================================================
 
 static Standard_Integer VConnect(Draw_Interpretor& di, 
                                  Standard_Integer argc, 
                                  const char ** argv) 
 {
-  // Check argumnets 
-  if(argc != 12)
+  // Check the viewer
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
   {
-    std::cout << "vconnect error: expect 11 argumnets\n"; 
+    std::cout << "vconnect error : call vinit before\n";
     return 1; // TCL_ERROR
   }
-  // Get values 
-  TCollection_AsciiString aName(argv[1]); 
-  TCollection_AsciiString anOriginObjectName(argv[2]); 
-  if(aName.IsEqual(anOriginObjectName))
+  // Check argumnets 
+  if (argc < 12)
   {
-    std::cout << "vconnect error: equal names for connected objects\n"; 
+    std::cout << "vconnect error: expect at least 11 arguments\n";
     return 1; // TCL_ERROR
   }
-  // Check if the origin shape is not null
+
+  // Get values
+  Standard_Integer anArgIter = 1;
+  TCollection_AsciiString aName (argv[anArgIter++]);
   Handle(AIS_InteractiveObject) anOriginObject;
-  if(GetMapOfAIS().IsBound2(anOriginObjectName))
+  TCollection_AsciiString aColorString (argv[argc-1]);
+  Standard_CString aColorName;
+  Standard_Boolean hasColor = Standard_False;
+  if (aColorString.Search ("color=") != -1)
   {
-    Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(anOriginObjectName);
-    anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
-    if(anOriginObject.IsNull())
+    hasColor = Standard_True;
+    aColorString.Remove (1, 6);
+    aColorName = aColorString.ToCString();
+  }
+  Handle(AIS_InteractiveObject) anObject;
+
+  // AIS_ConnectedInteractive
+  if (argc == 12 || (argc == 13 && hasColor))
+  {
+    TCollection_AsciiString anOriginObjectName(argv[11]);
+    if (aName.IsEqual (anOriginObjectName))
     {
-      std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n!";
+      std::cout << "vconnect error: equal names for connected objects\n"; 
       return 1; // TCL_ERROR
     }
+    if (GetMapOfAIS().IsBound2 (anOriginObjectName))
+    {
+      Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
+      anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
+      if (anOriginObject.IsNull())
+      {
+        std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
+        return 1; // TCL_ERROR
+      }
+    }
+    else
+    {
+      Standard_CString aName = anOriginObjectName.ToCString();
+      TopoDS_Shape aTDShape = DBRep::Get (aName);
+      if (aTDShape.IsNull())
+      {
+        std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
+        return 1; // TCL_ERROR
+      }
+      anOriginObject = new AIS_Shape (aTDShape);
+      if (hasColor)
+      {
+        anOriginObject->SetColor (ViewerTest::GetColorFromName (aColorName));
+      }
+    }
   }
-  
+  // AIS_MultipleConnectedInteractive
+  else
+  {
+    const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
+    for (Standard_Integer i = 11; i < aNbShapes; ++i)
+    {
+      TCollection_AsciiString anOriginObjectName (argv[i]);
+      if (aName.IsEqual (anOriginObjectName))
+      {
+        std::cout << "vconnect error: equal names for connected objects\n";
+        continue;
+      }
+      if (GetMapOfAIS().IsBound2 (anOriginObjectName))
+      {
+        Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
+        anObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
+        if (anObject.IsNull())
+        {
+          std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
+          continue;
+        }
+      }
+      else
+      {
+        Standard_CString aName = anOriginObjectName.ToCString();
+        TopoDS_Shape aTDShape = DBRep::Get (aName);
+        if (aTDShape.IsNull())
+        {
+          std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
+          continue;
+        }
+        anObject = new AIS_Shape (aTDShape);
+        anObject->SetColor (ViewerTest::GetColorFromName (aColorName));
+      }
+      if (anOriginObject.IsNull())
+      {
+        anOriginObject = new AIS_MultipleConnectedInteractive();
+        Handle(AIS_MultipleConnectedInteractive)::DownCast(anOriginObject)->Connect (anObject);
+      }
+      else
+      {
+        Handle(AIS_MultipleConnectedInteractive)::DownCast(anOriginObject)->Connect (anObject);
+      }
+    }
+    if (anOriginObject.IsNull())
+    {
+      std::cout << "vconect error : can't connect input objects\n";
+      return 1; // TCL_ERROR
+    }
+  }
+
   // Get location data
-  Standard_Real aXo = atof(argv[3]);
-  Standard_Real aYo = atof(argv[4]);
-  Standard_Real aZo = atof(argv[5]);
-  Standard_Real aXu = atof(argv[6]);
-  Standard_Real aXv = atof(argv[7]);
-  Standard_Real aXw = atof(argv[8]);
-  Standard_Real aZu = atof(argv[9]);
-  Standard_Real aZv = atof(argv[10]);
-  Standard_Real aZw = atof(argv[11]);
+  Standard_Real aXo = atof (argv[anArgIter++]);
+  Standard_Real aYo = atof (argv[anArgIter++]);
+  Standard_Real aZo = atof (argv[anArgIter++]);
+  Standard_Real aXu = atof (argv[anArgIter++]);
+  Standard_Real aXv = atof (argv[anArgIter++]);
+  Standard_Real aXw = atof (argv[anArgIter++]);
+  Standard_Real aZu = atof (argv[anArgIter++]);
+  Standard_Real aZv = atof (argv[anArgIter++]);
+  Standard_Real aZw = atof (argv[anArgIter++]);
 
   // Create transformation
   gp_Pnt aPoint(aXo, aYo, aZo);
@@ -3576,8 +3653,16 @@ static Standard_Integer VConnect(Draw_Interpretor& di,
   TopLoc_Location aLocation(aTrsf);
 
   // Create connected object
-  Handle(AIS_ConnectedInteractive) aConnectedObject = new AIS_ConnectedInteractive();
-  aConnectedObject->Connect(anOriginObject, aLocation);
+  Handle(AIS_ConnectedInteractive) aConnected = new AIS_ConnectedInteractive();
+  Handle(AIS_MultipleConnectedInteractive) anOrigin = Handle(AIS_MultipleConnectedInteractive)::DownCast(anOriginObject);
+  if (anOrigin.IsNull())
+  {
+    aConnected->Connect (anOriginObject, aLocation);
+  }
+  else
+  {
+    aConnected->Connect (anOrigin, aLocation);
+  }
 
   // Check if there is another object with given name
   // and remove it from context
@@ -3589,11 +3674,11 @@ static Standard_Integer VConnect(Draw_Interpretor& di,
     GetMapOfAIS().UnBind2(aName);
   }
 
-  // Bind connected object to its name 
-  GetMapOfAIS().Bind(aConnectedObject, aName); 
+  // Bind connected object to its name
+  GetMapOfAIS().Bind (aConnected, aName);
 
   // Display connected object
-  TheAISContext()->Display(aConnectedObject);
+  TheAISContext()->Display (aConnected);
 
   return 0;
 }
@@ -3601,50 +3686,141 @@ static Standard_Integer VConnect(Draw_Interpretor& di,
 //===============================================================================================
 //function : VConnectShape
 //purpose  : Creates and displays AIS_ConnectedShape from input shape and location 
-//Draw arg : vconnectsh name shape Xo Yo Zo Xu Xv Xw Zu Zv Zw
+//Draw arg : vconnectsh name Xo Yo Zo Xu Xv Xw Zu Zv Zw shape1 shape2 ... [color=NAME]
 //===============================================================================================
 
 static Standard_Integer VConnectShape(Draw_Interpretor& di, 
                                       Standard_Integer argc, 
                                       const char ** argv) 
 {
-  // Check argumnets 
-  if(argc != 12)
+  // Check the viewer
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
   {
-    std::cout << "vconnectsh error: expect 11 argumnets\n"; 
+    std::cout << "vconnectsh error : call vinit before\n";
     return 1; // TCL_ERROR
   }
-  // Get values 
-  TCollection_AsciiString aName(argv[1]); 
-  TCollection_AsciiString anOriginShapeName(argv[2]); 
-  if(aName.IsEqual(anOriginShapeName))
+  // Check argumnets
+  if (argc < 12)
   {
-    std::cout << "vconnectsh error: equal names for connected shapes\n"; 
+    std::cout << "vconnectsh error: expect at least 11 arguments\n";
     return 1; // TCL_ERROR
   }
-  // Check if the origin shape is not null
+
+  // Get values
+  Standard_Integer anArgIter = 1;
+  TCollection_AsciiString aName (argv[anArgIter++]);
   Handle(AIS_InteractiveObject) anOriginShape;
-  if(GetMapOfAIS().IsBound2(anOriginShapeName))
+  TCollection_AsciiString aColorString(argv[argc-1]);
+  Standard_CString aColorName;
+  Standard_Boolean hasColor = Standard_False;
+  if (aColorString.Search ("color=") != -1)
+  {
+    hasColor = Standard_True;
+    aColorString.Remove (1, 6);
+    aColorName = aColorString.ToCString();
+  }
+  Handle(AIS_Shape) aShape;
+
+  // AIS_ConnectedShape
+  if (argc == 12 || (argc == 13 && hasColor))
+  {
+    TCollection_AsciiString anOriginShapeName (argv[11]);
+    if (aName.IsEqual (anOriginShapeName))
+    {
+      std::cout << "vconnectsh error: equal names for connected shapes\n";
+      return 1; // TCL_ERROR
+    }
+    if (GetMapOfAIS().IsBound2 (anOriginShapeName))
+    {
+      Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginShapeName);
+      anOriginShape = Handle(AIS_Shape)::DownCast(anObj);
+      if (anOriginShape.IsNull())
+      {
+        std::cout << "Shape " << anOriginShapeName << " is used for non AIS viewer\n!";
+        return 1; // TCL_ERROR
+      }
+    }
+    else
+    {
+      Standard_CString aName = anOriginShapeName.ToCString();
+      TopoDS_Shape aTDShape = DBRep::Get (aName);
+      if (aTDShape.IsNull())
+      {
+        std::cout << "vconnectsh error: object " << anOriginShapeName << " doesn't exist\n";
+        return 1; // TCL_ERROR
+      }
+      anOriginShape = new AIS_Shape (aTDShape);
+      if (hasColor)
+      {
+        anOriginShape->SetColor (ViewerTest::GetColorFromName (aColorName));
+      }
+    }
+  }
+  // AIS_MultipleConnectedShape
+  else
   {
-    Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(anOriginShapeName);
-    anOriginShape = Handle(AIS_InteractiveObject)::DownCast(anObj);
-    if(anOriginShape.IsNull())
+    const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
+    for (Standard_Integer i = 11; i < aNbShapes; ++i)
+    {
+      TCollection_AsciiString anOriginShapeName (argv[i]);
+      if (aName.IsEqual (anOriginShapeName))
+      {
+        std::cout << "vconnectsh error: equal names for connected shapes\n";
+        continue;
+      }
+      if (GetMapOfAIS().IsBound2 (anOriginShapeName))
+      {
+        Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginShapeName);
+        aShape = Handle(AIS_Shape)::DownCast(anObj);
+        if (aShape.IsNull())
+        {
+          std::cout << "Shape " << anOriginShapeName << " is used for non AIS viewer\n";
+          continue;
+        }
+      }
+      else
+      {
+        Standard_CString aName = anOriginShapeName.ToCString();
+        TopoDS_Shape aTDShape = DBRep::Get (aName);
+        if (aTDShape.IsNull())
+        {
+          std::cout << "vconnectsh error: object " << anOriginShapeName << " doesn't exist\n";
+          continue;
+        }
+        aShape = new AIS_Shape (aTDShape);
+        if (hasColor)
+        {
+          aShape->SetColor (ViewerTest::GetColorFromName (aColorName));
+        }
+      }
+      if (anOriginShape.IsNull())
+      {
+        anOriginShape = new AIS_MultipleConnectedShape (aShape->Shape());
+        Handle(AIS_MultipleConnectedShape)::DownCast(anOriginShape)->Connect (aShape);
+      }
+      else
+      {
+        Handle(AIS_MultipleConnectedShape)::DownCast(anOriginShape)->Connect (aShape);
+      }
+    }
+    if (anOriginShape.IsNull())
     {
-      std::cout << "Shape " << anOriginShapeName << " is used for non AIS viewer\n!";
+      std::cout << "vconectsh error : can't connect input objects\n";
       return 1; // TCL_ERROR
     }
   }
 
   // Get location data  
-  Standard_Real aXo = atof(argv[3]);
-  Standard_Real aYo = atof(argv[4]);
-  Standard_Real aZo = atof(argv[5]);
-  Standard_Real aXu = atof(argv[6]);
-  Standard_Real aXv = atof(argv[7]);
-  Standard_Real aXw = atof(argv[8]);
-  Standard_Real aZu = atof(argv[9]);
-  Standard_Real aZv = atof(argv[10]);
-  Standard_Real aZw = atof(argv[11]);
+  Standard_Real aXo = atof (argv[anArgIter++]);
+  Standard_Real aYo = atof (argv[anArgIter++]);
+  Standard_Real aZo = atof (argv[anArgIter++]);
+  Standard_Real aXu = atof (argv[anArgIter++]);
+  Standard_Real aXv = atof (argv[anArgIter++]);
+  Standard_Real aXw = atof (argv[anArgIter++]);
+  Standard_Real aZu = atof (argv[anArgIter++]);
+  Standard_Real aZv = atof (argv[anArgIter++]);
+  Standard_Real aZw = atof (argv[anArgIter++]);
 
   // Create transformation
   gp_Pnt aPoint(aXo, aYo, aZo);
@@ -3660,9 +3836,18 @@ static Standard_Integer VConnectShape(Draw_Interpretor& di,
   TopLoc_Location aLocation(aTrsf);
 
   // Create connected shape
-  Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anOriginShape);
-  Handle(AIS_ConnectedShape) aConnectedShape = new AIS_ConnectedShape(aShape);
-  aConnectedShape->Connect(anOriginShape, aLocation);
+  Handle(AIS_ConnectedInteractive) aConnected;
+  Handle(AIS_Shape) anOrigin = Handle(AIS_Shape)::DownCast(anOriginShape);
+  if (!anOrigin.IsNull())
+  {
+    aConnected = new AIS_ConnectedShape (anOrigin);
+    aConnected->Connect (anOrigin, aLocation);
+  }
+  else
+  {
+    aConnected = new AIS_ConnectedInteractive();
+    aConnected->Connect (anOriginShape, aLocation);
+  }
 
   // Check if there is another object with given name
   // and remove it from context
@@ -3674,11 +3859,11 @@ static Standard_Integer VConnectShape(Draw_Interpretor& di,
     GetMapOfAIS().UnBind2(aName);
   }
 
-  // Bind connected shape to its name 
-  GetMapOfAIS().Bind(aConnectedShape, aName); 
+  // Bind connected shape to its name
+  GetMapOfAIS().Bind (aConnected, aName);
 
   // Display connected shape
-  TheAISContext()->Display(aConnectedShape);
+  TheAISContext()->Display (aConnected);
 
   return 0;
 }
@@ -4215,6 +4400,205 @@ static Standard_Integer VObjZLayer (Draw_Interpretor& di,
   return 0;
 }
 
+//=======================================================================
+//function : VPolygonOffset
+//purpose  : Set or get polygon offset parameters
+//=======================================================================
+static Standard_Integer VPolygonOffset(Draw_Interpretor& di,
+                                       Standard_Integer argc,
+                                       const char ** argv)
+{
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
+  {
+    std::cout << argv[0] << " Call 'vinit' before!\n";
+    return 1;
+  }
+
+  if (argc > 2 && argc != 5)
+  {
+    std::cout << "Usage : " << argv[0] << " [object [mode factor units]] - sets/gets polygon offset parameters for an object,"
+      "without arguments prints the default values" << std::endl;
+    return 1;
+  }
+
+  // find object
+  Handle(AIS_InteractiveObject) anInterObj;
+  if (argc >= 2)
+  {
+    TCollection_AsciiString aName (argv[1]);
+    ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
+    if (!aMap.IsBound2 (aName))
+    {
+      std::cout << "Use 'vdisplay' before" << std::endl;
+      return 1;
+    }
+
+    // find interactive object
+    Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
+    anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
+    if (anInterObj.IsNull())
+    {
+      std::cout << "Not an AIS interactive object!" << std::endl;
+      return 1;
+    }
+  }
+
+  Standard_Integer aMode;
+  Standard_ShortReal    aFactor, aUnits;
+  if (argc == 5)
+  {
+    aMode   = atoi(argv[2]);
+    aFactor = (Standard_ShortReal) atof(argv[3]);
+    aUnits  = (Standard_ShortReal) atof(argv[4]);
+
+    anInterObj->SetPolygonOffsets(aMode, aFactor, aUnits);
+    aContext->UpdateCurrentViewer();
+    return 0;
+  }
+  else if (argc == 2)
+  {
+    if (anInterObj->HasPolygonOffsets())
+    {
+      anInterObj->PolygonOffsets(aMode, aFactor, aUnits);
+      std::cout << "Current polygon offset parameters for " << argv[1] << ":" << std::endl;
+      std::cout << "\tMode: "   << aMode   << std::endl;
+      std::cout << "\tFactor: " << aFactor << std::endl;
+      std::cout << "\tUnits: "  << aUnits  << std::endl;
+      return 0;
+    }
+    else
+    {
+      std::cout << "Specific polygon offset parameters are not set for " << argv[1] << std::endl;
+    }
+  }
+
+  std::cout << "Default polygon offset parameters:" << std::endl;
+  aContext->DefaultDrawer()->ShadingAspect()->Aspect()->PolygonOffsets(aMode, aFactor, aUnits);
+  std::cout << "\tMode: "   << aMode   << std::endl;
+  std::cout << "\tFactor: " << aFactor << std::endl;
+  std::cout << "\tUnits: "  << aUnits  << std::endl;
+
+  return 0;
+}
+
+//=======================================================================
+//function : VShowFaceBoundaries
+//purpose  : Set face boundaries drawing on/off for ais object
+//=======================================================================
+static Standard_Integer VShowFaceBoundary (Draw_Interpretor& di,
+                                           Standard_Integer argc,
+                                           const char ** argv)
+{
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext ();
+  if (aContext.IsNull ())
+  {
+    std::cout << argv[0] << " Call 'vinit' before!\n";
+    return 1;
+  }
+
+  if ((argc != 3 && argc < 6) || argc > 8)
+  {
+    std::cout << "Usage :\n " << argv[0]
+              << " ObjectName isOn [R G B [LineWidth [LineStyle]]]\n"
+              << "   ObjectName - name of AIS interactive object. \n"
+              << "                if ObjectName = \"\", then set as default\n"
+              << "                settings for all newly displayed objects\n"
+              << "   isOn       - flag indicating whether the boundaries\n"
+              << "                should be turned on or off (can be set\n"
+              << "                to 0 (off) or 1 (on)).\n"
+              << "   R, G, B    - red, green and blue components of boundary\n"
+              << "                color in range (0 - 255).\n"
+              << "                (default is (0, 0, 0)\n"
+              << "   LineWidth  - line width\n"
+              << "                (default is 1)\n"
+              << "   LineStyle  - line fill style :\n"
+              << "                 0 - solid  \n"
+              << "                 1 - dashed \n"
+              << "                 2 - dot    \n"
+              << "                 3 - dashdot\n"
+              << "                 (default is solid)";
+    return 1;
+  }
+
+  TCollection_AsciiString aName (argv[1]);
+
+  Quantity_Parameter aRed      = 0.0;
+  Quantity_Parameter aGreen    = 0.0;
+  Quantity_Parameter aBlue     = 0.0;
+  Standard_Real      aWidth    = 1.0;
+  Aspect_TypeOfLine  aLineType = Aspect_TOL_SOLID;
+  
+  // find object
+  Handle(AIS_InteractiveObject) anInterObj;
+
+  // if name is empty - apply attributes for default aspect
+  if (!aName.IsEmpty ())
+  {
+    ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS ();
+    if (!aMap.IsBound2 (aName))
+    {
+      std::cout << "Use 'vdisplay' on " << aName << " before" << std::endl;
+      return 1;
+    }
+
+    // find interactive object
+    Handle(Standard_Transient) anObj = GetMapOfAIS ().Find2 (aName);
+    anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
+    if (anInterObj.IsNull ())
+    {
+      std::cout << "Not an AIS interactive object!" << std::endl;
+      return 1;
+    }
+  }
+  
+  const Handle(Prs3d_Drawer)& aDrawer = (aName.IsEmpty ()) ?
+    TheAISContext ()->DefaultDrawer () : anInterObj->Attributes ();
+
+  // turn boundaries on/off
+  Standard_Boolean isBoundaryDraw = (atoi (argv[2]) == 1);
+  aDrawer->SetFaceBoundaryDraw (isBoundaryDraw);
+  
+  // set boundary line color
+  if (argc >= 6)
+  {
+    // Text color
+    aRed   = atof (argv[3])/255.;
+    aGreen = atof (argv[4])/255.;
+    aBlue  = atof (argv[5])/255.;
+  }
+
+  // set line width
+  if (argc >= 7)
+  {
+    aWidth = (Standard_Real)atof (argv[6]);
+  }
+
+  // select appropriate line type
+  if (argc == 8)
+  {
+    switch (atoi (argv[7]))
+    {
+      case 1: aLineType = Aspect_TOL_DASH;    break;
+      case 2: aLineType = Aspect_TOL_DOT;     break;
+      case 3: aLineType = Aspect_TOL_DOTDASH; break;
+      default:
+        aLineType = Aspect_TOL_SOLID;
+    }
+  }
+
+  Quantity_Color aColor (aRed, aGreen, aBlue, Quantity_TOC_RGB);
+
+  Handle(Prs3d_LineAspect) aBoundaryAspect = 
+    new Prs3d_LineAspect (aColor, aLineType, aWidth);
+
+  aDrawer->SetFaceBoundaryAspect (aBoundaryAspect);
+
+  TheAISContext()->Redisplay (anInterObj);
+  
+  return 0;
+}
+
 //=======================================================================
 //function : ObjectsCommands
 //purpose  :
@@ -4297,15 +4681,15 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
     __FILE__, VComputeHLR, group);
 
   theCommands.Add("vdrawparray",
-    "vdrawparray : vdrawparray Name TypeOfArray [EnableVbo=1] [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id [edge_hidden = { 'h' }] ]",
+    "vdrawparray : vdrawparray Name TypeOfArray [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id [edge_hidden = { 'h' }] ]",
     __FILE__,VDrawPArray,group);
 
   theCommands.Add("vconnect", 
-    "vconnect : name object Xo Yo Zo Xu Xv Xw Zu Zv Zw", 
+    "vconnect : name Xo Yo Zo Xu Xv Xw Zu Zv Zw object1 object2 ... [color=NAME]", 
     __FILE__, VConnect, group);
 
   theCommands.Add("vconnectsh", 
-    "vconnectsh : name shape Xo Yo Zo Xu Xv Xw Zu Zv Zw", 
+    "vconnectsh : name Xo Yo Zo Xu Xv Xw Zu Zv Zw shape1 shape2 ... [color=NAME]", 
     __FILE__, VConnectShape, group);
 
   theCommands.Add("vselmode", 
@@ -4323,4 +4707,14 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
   theCommands.Add("vobjzlayer",
     "vobjzlayer : set/get object [layerid] - set or get z layer id for the interactive object",
     __FILE__, VObjZLayer, group);
+  
+  theCommands.Add("vpolygonoffset",
+    "vpolygonoffset : [object [mode factor units]] - sets/gets polygon offset parameters for an object, without arguments prints the default values",
+    __FILE__, VPolygonOffset, group);
+
+  theCommands.Add ("vshowfaceboundary",
+    "vshowfaceboundary : ObjectName isOn (1/0) [R G B [LineWidth [LineStyle]]]"
+    "- turns on/off drawing of face boundaries for ais object "
+    "and defines boundary line style.",
+    __FILE__, VShowFaceBoundary, group);
 }