0030180: Data Exchange - VrmlAPI_Writer is expected to return export state
[occt.git] / src / XSDRAWSTLVRML / XSDRAWSTLVRML.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 1eb7656..cf86dc0
-// File:  XSDRAWSTLVRML.cxx
-// Created: Tue May 30 17:29:50 2000
-// Author:  Sergey MOZOKHIN
-//    <smh@russox.nnov.matra-dtv.fr>
+// Created on: 2000-05-30
+// Created by: Sergey MOZOKHIN
+// Copyright (c) 2000-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 
-#include <XSDRAWSTLVRML.ixx>
-#include <Draw_Interpretor.hxx>
-#include <TopoDS_Shape.hxx>
-#include <VrmlAPI.hxx>
-#include <OSD_Path.hxx>
-#include <StlAPI.hxx>
-#include <XSDRAW.hxx>
-#include <DBRep.hxx>
-#include <VrmlAPI_Writer.hxx>
-#include <Quantity_Color.hxx>
-#include <Quantity_HArray1OfColor.hxx>
-#include <StlAPI_Writer.hxx>
-#include <Draw_PluginMacro.hxx>
-#include <SWDRAW.hxx>
-#include <XSDRAW.hxx>
-#include <XSDRAWSTEP.hxx>
-#include <XSDRAWIGES.hxx>
 #include <AIS_InteractiveContext.hxx>
-#include <ViewerTest.hxx>
+#include <Aspect_TypeOfMarker.hxx>
+#include <Bnd_Box.hxx>
+#include <BRep_Builder.hxx>
+#include <DBRep.hxx>
+#include <DDocStd.hxx>
+#include <DDocStd_DrawDocument.hxx>
 #include <Draw.hxx>
+#include <Draw_Interpretor.hxx>
+#include <Draw_PluginMacro.hxx>
 #include <Draw_ProgressIndicator.hxx>
-#include <RWStl.hxx>
-#include <Quantity_Color.hxx>
-#include <V3d_View.hxx>
-#include <TCollection_AsciiString.hxx>
-
-#include <SelectMgr_SelectionManager.hxx>
-#include <StdSelect_ViewerSelector3d.hxx>
-
-#include <Aspect_TypeOfMarker.hxx>
 #include <Graphic3d_MaterialAspect.hxx>
-
-#include <StlMesh_Mesh.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
-
-#include <MeshVS_Mesh.hxx>
-#include <MeshVS_MeshPrsBuilder.hxx>
-#include <MeshVS_TextPrsBuilder.hxx>
+#include <MeshVS_DataMapOfIntegerAsciiString.hxx>
+#include <MeshVS_DeformedDataSource.hxx>
 #include <MeshVS_Drawer.hxx>
 #include <MeshVS_DrawerAttribute.hxx>
+#include <MeshVS_ElementalColorPrsBuilder.hxx>
+#include <MeshVS_Mesh.hxx>
 #include <MeshVS_MeshEntityOwner.hxx>
-#include <MeshVS_DataMapOfIntegerAsciiString.hxx>
-
-#include <XSDRAWSTLVRML_DataSource.hxx>
-#include <XSDRAWSTLVRML_DrawableMesh.hxx>
+#include <MeshVS_MeshPrsBuilder.hxx>
 #include <MeshVS_NodalColorPrsBuilder.hxx>
-#include <MeshVS_ElementalColorPrsBuilder.hxx>
+#include <MeshVS_PrsBuilder.hxx>
+#include <MeshVS_TextPrsBuilder.hxx>
+#include <MeshVS_VectorPrsBuilder.hxx>
+#include <OSD_Path.hxx>
+#include <Quantity_Color.hxx>
+#include <Quantity_HArray1OfColor.hxx>
 #include <Quantity_NameOfColor.hxx>
+#include <RWGltf_CafReader.hxx>
+#include <RWStl.hxx>
+#include <RWObj.hxx>
+#include <RWObj_CafReader.hxx>
+#include <SelectMgr_SelectionManager.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <StdSelect_ViewerSelector3d.hxx>
+#include <StlAPI.hxx>
+#include <StlAPI_Writer.hxx>
 #include <TColgp_SequenceOfXYZ.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HPackedMapOfInteger.hxx>
 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
-#include <Standard_ErrorHandler.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDocStd_Application.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <UnitsAPI.hxx>
+#include <UnitsMethods.hxx>
+#include <V3d_View.hxx>
+#include <ViewerTest.hxx>
+#include <VrmlAPI.hxx>
+#include <VrmlAPI_Writer.hxx>
+#include <VrmlData_DataMapOfShapeAppearance.hxx>
 #include <VrmlData_Scene.hxx>
 #include <VrmlData_ShapeConvert.hxx>
-#include <VrmlData_DataMapOfShapeAppearance.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <Bnd_Box.hxx>
-
-// avoid warnings on 'extern "C"' functions returning C++ classes
-#ifdef WNT
-#pragma warning(4:4190)
-#endif
+#include <XSDRAW.hxx>
+#include <XSDRAWIGES.hxx>
+#include <XSDRAWSTEP.hxx>
+#include <XSDRAWSTLVRML.hxx>
+#include <XSDRAWSTLVRML_DataSource.hxx>
+#include <XSDRAWSTLVRML_DataSource3D.hxx>
+#include <XSDRAWSTLVRML_DrawableMesh.hxx>
 
 #ifndef _STDIO_H
 #include <stdio.h>
 #endif
 
+extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
+                                           const Handle(AIS_InteractiveObject)& theAISObj,
+                                           Standard_Boolean theReplaceIfExists = Standard_True);
+
+//=============================================================================
+//function : ReadGltf
+//purpose  : Reads glTF file
+//=============================================================================
+static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
+                                  Standard_Integer theNbArgs,
+                                  const char** theArgVec)
+{
+  TCollection_AsciiString aDestName, aFilePath;
+  Standard_Boolean toUseExistingDoc = Standard_False;
+  Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
+  Standard_Boolean toListExternalFiles = Standard_False;
+  Standard_Boolean isParallel = Standard_False;
+  Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readgltf");
+  for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
+    anArgCase.LowerCase();
+    if (!isNoDoc
+     && (anArgCase == "-nocreate"
+      || anArgCase == "-nocreatedoc"))
+    {
+      toUseExistingDoc = Standard_True;
+      if (anArgIter + 1 < theNbArgs
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toUseExistingDoc))
+      {
+        ++anArgIter;
+      }
+    }
+    else if (anArgCase == "-parallel")
+    {
+      isParallel = Standard_True;
+      if (anArgIter + 1 < theNbArgs
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isParallel))
+      {
+        ++anArgIter;
+      }
+    }
+    else if (anArgCase == "-listexternalfiles"
+          || anArgCase == "-listexternals"
+          || anArgCase == "-listexternal"
+          || anArgCase == "-external"
+          || anArgCase == "-externalfiles")
+    {
+      toListExternalFiles = Standard_True;
+    }
+    else if (aDestName.IsEmpty())
+    {
+      aDestName = theArgVec[anArgIter];
+    }
+    else if (aFilePath.IsEmpty())
+    {
+      aFilePath = theArgVec[anArgIter];
+    }
+    else
+    {
+      std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+      return 1;
+    }
+  }
+  if (aFilePath.IsEmpty())
+  {
+    std::cout << "Syntax error: wrong number of arguments\n";
+    return 1;
+  }
+
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
+  Handle(TDocStd_Document) aDoc;
+  if (!toListExternalFiles
+   && !isNoDoc)
+  {
+    Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
+    Standard_CString aNameVar = aDestName.ToCString();
+    DDocStd::GetDocument (aNameVar, aDoc, Standard_False);
+    if (aDoc.IsNull())
+    {
+      if (toUseExistingDoc)
+      {
+        std::cout << "Error: document with name " << aDestName << " does not exist\n";
+        return 1;
+      }
+      anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
+    }
+    else if (!toUseExistingDoc)
+    {
+      std::cout << "Error: document with name " << aDestName << " already exists\n";
+      return 1;
+    }
+  }
+
+  RWGltf_CafReader aReader;
+  aReader.SetSystemLengthUnit (aSystemUnitFactor);
+  aReader.SetSystemCoordinateSystem (RWMesh_CoordinateSystem_Zup);
+  aReader.SetDocument (aDoc);
+  aReader.SetParallel (isParallel);
+  if (toListExternalFiles)
+  {
+    aReader.ProbeHeader (aFilePath);
+    for (NCollection_IndexedMap<TCollection_AsciiString>::Iterator aFileIter (aReader.ExternalFiles()); aFileIter.More(); aFileIter.Next())
+    {
+      theDI << "\"" << aFileIter.Value() << "\" ";
+    }
+  }
+  else
+  {
+    aReader.Perform (aFilePath, aProgress);
+    if (isNoDoc)
+    {
+      DBRep::Set (aDestName.ToCString(), aReader.SingleShape());
+    }
+    else
+    {
+      Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
+      TDataStd_Name::Set (aDoc->GetData()->Root(), aDestName.ToCString());
+      Draw::Set (aDestName.ToCString(), aDrawDoc);
+    }
+  }
+  return 0;
+}
+
 static Standard_Integer writestl
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  if (argc<3) di << "wrong number of parameters"    << "\n";
-  else {
-    TopoDS_Shape shape = DBRep::Get(argv[1]);
-    //     StlAPI_Writer writer;
-    //     writer.ASCIIMode() = Standard_False;
-    //     writer.Write (shape, "binary.stl");
-    StlAPI::Write(shape, argv[2],Standard_False); //now write in binary mode
+  if (argc < 3 || argc > 4) {
+    di << "Use: " << argv[0]
+    << " shape file [ascii/binary (0/1) : 1 by default]\n";
+  } else {
+    TopoDS_Shape aShape = DBRep::Get(argv[1]);
+    Standard_Boolean isASCIIMode = Standard_False;
+    if (argc == 4) {
+      isASCIIMode = (Draw::Atoi(argv[3]) == 0);
+    }
+    StlAPI_Writer aWriter;
+    aWriter.ASCIIMode() = isASCIIMode;
+    Standard_Boolean isOK = aWriter.Write (aShape, argv[2]);
+    if (!isOK)
+       di << "** Error **: Mesh writing has been failed.\n";
   }
   return 0;
 }
 
-static Standard_Integer readstl
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+//=============================================================================
+//function : readstl
+//purpose  : Reads stl file
+//=============================================================================
+static Standard_Integer readstl(Draw_Interpretor& theDI,
+                                Standard_Integer theArgc,
+                                const char** theArgv)
 {
-  if (argc<3) di << "wrong number of parameters"    << "\n";
-  else {
-    TopoDS_Shape shape ;
-    StlAPI::Read(shape,argv[2]);
-    DBRep::Set(argv[1],shape);
+  TCollection_AsciiString aShapeName, aFilePath;
+  bool toCreateCompOfTris = false;
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgv[anArgIter]);
+    anArg.LowerCase();
+    if (aShapeName.IsEmpty())
+    {
+      aShapeName = theArgv[anArgIter];
+    }
+    else if (aFilePath.IsEmpty())
+    {
+      aFilePath = theArgv[anArgIter];
+    }
+    else if (anArg == "-brep")
+    {
+      toCreateCompOfTris = true;
+      if (anArgIter + 1 < theArgc
+       && ViewerTest::ParseOnOff (theArgv[anArgIter + 1], toCreateCompOfTris))
+      {
+        ++anArgIter;
+      }
+    }
+    else
+    {
+      std::cout << "Syntax error: unknown argument '" << theArgv[anArgIter] << "'\n";
+      return 1;
+    }
+  }
+  if (aFilePath.IsEmpty())
+  {
+    std::cout << "Syntax error: not enough arguments\n";
+    return 1;
+  }
+
+  TopoDS_Shape aShape;
+  if (!toCreateCompOfTris)
+  {
+    // Read STL file to the triangulation.
+    Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
+    Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (aFilePath.ToCString(), aProgress);
+
+    TopoDS_Face aFace;
+    BRep_Builder aB;
+    aB.MakeFace (aFace);
+    aB.UpdateFace (aFace, aTriangulation);
+    aShape = aFace;
+  }
+  else
+  {
+    Standard_DISABLE_DEPRECATION_WARNINGS
+    StlAPI::Read(aShape, aFilePath.ToCString());
+    Standard_ENABLE_DEPRECATION_WARNINGS
+  }
+  DBRep::Set (aShapeName.ToCString(), aShape);
+  return 0;
+}
+
+//! Parse RWMesh_CoordinateSystem enumeration.
+static Standard_Boolean parseCoordinateSystem (const char* theArg,
+                                               RWMesh_CoordinateSystem& theSystem)
+{
+  TCollection_AsciiString aCSStr (theArg);
+  aCSStr.LowerCase();
+  if (aCSStr == "zup")
+  {
+    theSystem = RWMesh_CoordinateSystem_Zup;
+  }
+  else if (aCSStr == "yup")
+  {
+    theSystem = RWMesh_CoordinateSystem_Yup;
+  }
+  else
+  {
+    return Standard_False;
+  }
+  return Standard_True;
+}
+
+//=============================================================================
+//function : ReadObj
+//purpose  : Reads OBJ file
+//=============================================================================
+static Standard_Integer ReadObj (Draw_Interpretor& theDI,
+                                 Standard_Integer theNbArgs,
+                                 const char** theArgVec)
+{
+  TCollection_AsciiString aDestName, aFilePath;
+  Standard_Boolean toUseExistingDoc = Standard_False;
+  Standard_Real aFileUnitFactor = -1.0;
+  RWMesh_CoordinateSystem aResultCoordSys = RWMesh_CoordinateSystem_Zup, aFileCoordSys = RWMesh_CoordinateSystem_Yup;
+  Standard_Boolean toListExternalFiles = Standard_False, isSingleFace = Standard_False, isSinglePrecision = Standard_False;
+  Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readobj");
+  for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
+    anArgCase.LowerCase();
+    if (anArgIter + 1 < theNbArgs
+     && (anArgCase == "-unit"
+      || anArgCase == "-units"
+      || anArgCase == "-fileunit"
+      || anArgCase == "-fileunits"))
+    {
+      const TCollection_AsciiString aUnitStr (theArgVec[++anArgIter]);
+      aFileUnitFactor = UnitsAPI::AnyToSI (1.0, aUnitStr.ToCString());
+      if (aFileUnitFactor <= 0.0)
+      {
+        std::cout << "Syntax error: wrong length unit '" << aUnitStr << "'\n";
+        return 1;
+      }
+    }
+    else if (anArgIter + 1 < theNbArgs
+          && (anArgCase == "-filecoordinatesystem"
+           || anArgCase == "-filecoordsystem"
+           || anArgCase == "-filecoordsys"))
+    {
+      if (!parseCoordinateSystem (theArgVec[++anArgIter], aFileCoordSys))
+      {
+        std::cout << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'\n";
+        return 1;
+      }
+    }
+    else if (anArgIter + 1 < theNbArgs
+          && (anArgCase == "-resultcoordinatesystem"
+           || anArgCase == "-resultcoordsystem"
+           || anArgCase == "-resultcoordsys"
+           || anArgCase == "-rescoordsys"))
+    {
+      if (!parseCoordinateSystem (theArgVec[++anArgIter], aResultCoordSys))
+      {
+        std::cout << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'\n";
+        return 1;
+      }
+    }
+    else if (anArgCase == "-singleprecision"
+          || anArgCase == "-singleprec")
+    {
+      isSinglePrecision = Standard_True;
+      if (anArgIter + 1 < theNbArgs
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isSinglePrecision))
+      {
+        ++anArgIter;
+      }
+    }
+    else if (isNoDoc
+          && (anArgCase == "-singleface"
+           || anArgCase == "-singletriangulation"))
+    {
+      isSingleFace = Standard_True;
+    }
+    else if (!isNoDoc
+          && (anArgCase == "-nocreate"
+           || anArgCase == "-nocreatedoc"))
+    {
+      toUseExistingDoc = Standard_True;
+      if (anArgIter + 1 < theNbArgs
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toUseExistingDoc))
+      {
+        ++anArgIter;
+      }
+    }
+    else if (anArgCase == "-listexternalfiles"
+          || anArgCase == "-listexternals"
+          || anArgCase == "-listexternal"
+          || anArgCase == "-external"
+          || anArgCase == "-externalfiles")
+    {
+      toListExternalFiles = Standard_True;
+    }
+    else if (aDestName.IsEmpty())
+    {
+      aDestName = theArgVec[anArgIter];
+    }
+    else if (aFilePath.IsEmpty())
+    {
+      aFilePath = theArgVec[anArgIter];
+    }
+    else
+    {
+      std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+      return 1;
+    }
+  }
+  if (aFilePath.IsEmpty())
+  {
+    std::cout << "Syntax error: wrong number of arguments\n";
+    return 1;
+  }
+
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
+  Handle(TDocStd_Document) aDoc;
+  if (!isNoDoc
+   && !toListExternalFiles)
+  {
+    Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
+    Standard_CString aNameVar = aDestName.ToCString();
+    DDocStd::GetDocument (aNameVar, aDoc, Standard_False);
+    if (aDoc.IsNull())
+    {
+      if (toUseExistingDoc)
+      {
+        std::cout << "Error: document with name " << aDestName << " does not exist\n";
+        return 1;
+      }
+      anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
+    }
+    else if (!toUseExistingDoc)
+    {
+      std::cout << "Error: document with name " << aDestName << " already exists\n";
+      return 1;
+    }
+  }
+
+  RWObj_CafReader aReader;
+  aReader.SetSinglePrecision (isSinglePrecision);
+  aReader.SetSystemLengthUnit (UnitsMethods::GetCasCadeLengthUnit() * 0.001);
+  aReader.SetSystemCoordinateSystem (aResultCoordSys);
+  aReader.SetFileLengthUnit (aFileUnitFactor);
+  aReader.SetFileCoordinateSystem (aFileCoordSys);
+  aReader.SetDocument (aDoc);
+  if (isSingleFace)
+  {
+    RWObj_TriangulationReader aSimpleReader;
+    aSimpleReader.SetSinglePrecision (isSinglePrecision);
+    aSimpleReader.SetCreateShapes (Standard_False);
+    aSimpleReader.SetTransformation (aReader.CoordinateSystemConverter());
+    aSimpleReader.Read (aFilePath.ToCString(), aProgress);
+
+    Handle(Poly_Triangulation) aTriangulation = aSimpleReader.GetTriangulation();
+    TopoDS_Face aFace;
+    BRep_Builder aBuiler;
+    aBuiler.MakeFace (aFace);
+    aBuiler.UpdateFace (aFace, aTriangulation);
+    DBRep::Set (aDestName.ToCString(), aFace);
+    return 0;
+  }
+
+  if (toListExternalFiles)
+  {
+    aReader.ProbeHeader (aFilePath);
+    for (NCollection_IndexedMap<TCollection_AsciiString>::Iterator aFileIter (aReader.ExternalFiles()); aFileIter.More(); aFileIter.Next())
+    {
+      theDI << "\"" << aFileIter.Value() << "\" ";
+    }
+  }
+  else
+  {
+    aReader.Perform (aFilePath, aProgress);
+    if (isNoDoc)
+    {
+      DBRep::Set (aDestName.ToCString(), aReader.SingleShape());
+    }
+    else
+    {
+      Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
+      TDataStd_Name::Set (aDoc->GetData()->Root(), aDestName.ToCString());
+      Draw::Set (aDestName.ToCString(), aDrawDoc);
+    }
   }
   return 0;
 }
@@ -100,21 +499,44 @@ static Standard_Integer readstl
 static Standard_Integer writevrml
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  if (argc<3) di << "wrong number of parameters"    << "\n";
-  else {
-    TopoDS_Shape shape = DBRep::Get(argv[1]);
-    //     VrmlAPI_Writer writer;
-    //     writer.SetTransparencyToMaterial(writer.GetFrontMaterial(),0.0);
-    //      Quantity_Color color;
-    //      color.SetValues(Quantity_NOC_GOLD);
-    //      Handle(Quantity_HArray1OfColor) Col = new Quantity_HArray1OfColor(1,1);
-    //      Col->SetValue(1,color);
-    //      writer.SetDiffuseColorToMaterial(writer.GetFrontMaterial(),Col);
-    //      writer.SetRepresentation(VrmlAPI_ShadedRepresentation);
-    //      writer.SetDeflection(0.01);
-    //      writer.Write(shape, argv[2]);
-    VrmlAPI::Write(shape, argv[2]);
+  if (argc < 3 || argc > 5) 
+  {
+    di << "wrong number of parameters\n";
+    return 0;
+  }
+
+  TopoDS_Shape aShape = DBRep::Get(argv[1]);
+
+  // Get the optional parameters
+  Standard_Integer aVersion = 2;
+  Standard_Integer aType = 1;
+  if (argc >= 4)
+  {
+    aVersion = Draw::Atoi(argv[3]);
+    if (argc == 5)
+      aType = Draw::Atoi(argv[4]);
+  }
+
+  // Bound parameters
+  aVersion = Max(1, aVersion);
+  aVersion = Min(2, aVersion);
+  aType = Max(0, aType);
+  aType = Min(2, aType);
+
+  VrmlAPI_Writer writer;
+
+  switch (aType)
+  {
+  case 0: writer.SetRepresentation(VrmlAPI_ShadedRepresentation); break;
+  case 1: writer.SetRepresentation(VrmlAPI_WireFrameRepresentation); break;
+  case 2: writer.SetRepresentation(VrmlAPI_BothRepresentation); break;
   }
+
+  if (!writer.Write(aShape, argv[2], aVersion))
+  {
+    di << "Error: File " << argv[2] << " was not written\n";
+  }
+
   return 0;
 }
 
@@ -128,53 +550,74 @@ static Standard_Integer loadvrml
 {
   if (argc<3) di << "wrong number of parameters"    << "\n";
   else {
-    TopoDS_Shape shape ;
-    VrmlData_DataMapOfShapeAppearance ShapeAppMap;
+    TopoDS_Shape aShape ;
+    VrmlData_DataMapOfShapeAppearance aShapeAppMap;
 
     //-----------------------------------------------------------
-    filebuf fic;
-    istream aStream (&fic);
+    std::filebuf aFic;
+    std::istream aStream (&aFic);
+
+    if (aFic.open(argv[2], std::ios::in)) {
 
-    if (fic.open(argv[2], ios::in)) {
+      // Get path of the VRML file.
+      OSD_Path aPath(argv[2]);
+      TCollection_AsciiString aVrmlDir(".");
+      TCollection_AsciiString aDisk = aPath.Disk();
+      TCollection_AsciiString aTrek = aPath.Trek();
+      if (!aTrek.IsEmpty())
+      {
+        if (!aDisk.IsEmpty())
+          aVrmlDir = aDisk;
+        else
+          aVrmlDir.Clear();
+        aTrek.ChangeAll('|', '/');
+        aVrmlDir += aTrek;
+      }
 
       VrmlData_Scene aScene;
+      Standard_Real anOCCUnit = UnitsMethods::GetCasCadeLengthUnit();
+      aScene.SetLinearScale(1000. / anOCCUnit);
 
-      aScene.SetVrmlDir (".");
+      aScene.SetVrmlDir (aVrmlDir);
       aScene << aStream;
       const char * aStr = 0L;
       switch (aScene.Status()) {
 
       case VrmlData_StatusOK:
         {
-          shape = aScene.GetShape(ShapeAppMap);
+          aShape = aScene.GetShape(aShapeAppMap);
           break;
         }
-      case VrmlData_EmptyData:          aStr = "EmptyData"; break;
-      case VrmlData_UnrecoverableError: aStr = "UnrecoverableError"; break;
-      case VrmlData_GeneralError:       aStr = "GeneralError"; break;
-      case VrmlData_EndOfFile:          aStr = "EndOfFile"; break;
-      case VrmlData_NotVrmlFile:        aStr = "NotVrmlFile"; break;
-      case VrmlData_CannotOpenFile:     aStr = "CannotOpenFile"; break;
-      case VrmlData_VrmlFormatError:    aStr = "VrmlFormatError"; break;
-      case VrmlData_NumericInputError:  aStr = "NumericInputError"; break;
-      case VrmlData_IrrelevantNumber:   aStr = "IrrelevantNumber"; break;
-      case VrmlData_BooleanInputError:  aStr = "BooleanInputError"; break;
-      case VrmlData_StringInputError:   aStr = "StringInputError"; break;
-      case VrmlData_NodeNameUnknown:    aStr = "NodeNameUnknown"; break;
-      case VrmlData_NonPositiveSize:    aStr = "NonPositiveSize"; break;
-      case VrmlData_ReadUnknownNode:    aStr = "ReadUnknownNode"; break;
-      case VrmlData_NonSupportedFeature:aStr = "NonSupportedFeature"; break;
+      case VrmlData_EmptyData:            aStr = "EmptyData"; break;
+      case VrmlData_UnrecoverableError:   aStr = "UnrecoverableError"; break;
+      case VrmlData_GeneralError:         aStr = "GeneralError"; break;
+      case VrmlData_EndOfFile:            aStr = "EndOfFile"; break;
+      case VrmlData_NotVrmlFile:          aStr = "NotVrmlFile"; break;
+      case VrmlData_CannotOpenFile:       aStr = "CannotOpenFile"; break;
+      case VrmlData_VrmlFormatError:      aStr = "VrmlFormatError"; break;
+      case VrmlData_NumericInputError:    aStr = "NumericInputError"; break;
+      case VrmlData_IrrelevantNumber:     aStr = "IrrelevantNumber"; break;
+      case VrmlData_BooleanInputError:    aStr = "BooleanInputError"; break;
+      case VrmlData_StringInputError:     aStr = "StringInputError"; break;
+      case VrmlData_NodeNameUnknown:      aStr = "NodeNameUnknown"; break;
+      case VrmlData_NonPositiveSize:      aStr = "NonPositiveSize"; break;
+      case VrmlData_ReadUnknownNode:      aStr = "ReadUnknownNode"; break;
+      case VrmlData_NonSupportedFeature:  aStr = "NonSupportedFeature"; break;
+      case VrmlData_OutputStreamUndefined:aStr = "OutputStreamUndefined"; break;
+      case VrmlData_NotImplemented:       aStr = "NotImplemented"; break;
+      default:
+        break;
       }
       if (aStr) {
         di << " ++ VRML Error: " << aStr << " in line "
           << aScene.GetLineError() << "\n";
       }
       else {
-        DBRep::Set(argv[1],shape);
+        DBRep::Set(argv[1],aShape);
       }
     }
     else {
-      di << "cannot open file" << "\n";
+      di << "cannot open file\n";
     }
 
 
@@ -183,291 +626,198 @@ static Standard_Integer loadvrml
   return 0;
 }
 
-//=======================================================================
-//function : storevrml
-//purpose  :
-//=======================================================================
-
-static Standard_Integer storevrml
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
-{
-  if (argc < 4) {
-    di << "wrong number of parameters"    << "\n";
-    di << "use: storevrml shape file defl type_of_conversion (0, 1, 2)"    << "\n";
-  }
-  else {
-    TopAbs_ShapeEnum Types[3] = {TopAbs_FACE, TopAbs_WIRE, TopAbs_EDGE};
-    TopoDS_Shape shape = DBRep::Get(argv[1]);
-    Standard_Real defl = atof(argv[3]);
-    Standard_Integer type = 1;
-    if(argc > 4) type = atoi(argv[4]);
-    type = Max(0, type);
-    type = Min(2, type);
-
-    Standard_Boolean ExtFace = Standard_False;
-    if(type == 0 || type == 2) ExtFace = Standard_True;
-    Standard_Boolean ExtEdge = Standard_False;
-    if(type == 1 || type == 2) ExtEdge = Standard_True;
-
-    VrmlData_Scene aScene;
-    VrmlData_ShapeConvert Conv(aScene);
-    Conv.AddShape(shape);
-    Conv.Convert(ExtFace, ExtEdge, defl);
-
-    filebuf foc;
-    ostream outStream (&foc);
-    if (foc.open (argv[2], ios::out))
-      outStream << aScene;
-  }
-  return 0;
-}
-
-
 //-----------------------------------------------------------------------------
 static Standard_Integer createmesh
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
-
   if (argc<3)
   {
-    di << "Use: " << argv[0] << " <mesh name> <stl file>" << "\n";
-    return 1;
+    di << "Wrong number of parameters\n";
+    di << "Use: " << argv[0] << " <mesh name> <stl file>\n";
+    return 0;
+  }
+
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
+  {
+    di << "No active view. Please call 'vinit' first\n";
+    return 0;
   }
 
   // Progress indicator
   OSD_Path aFile( argv[2] );
   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
-  Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFile, aProgress);
+  Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFile, aProgress);
 
-  di << "Reading OK..." << "\n";
+  di << "Reading OK...\n";
   Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
-  di << "Data source is created successful" << "\n";
+  di << "Data source is created successful\n";
   Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
-  di << "MeshVS_Mesh is created successful" << "\n";
+  di << "MeshVS_Mesh is created successful\n";
 
   aMesh->SetDataSource( aDS );
   aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
-  // Prepare triangle labels
-  MeshVS_DataMapOfIntegerAsciiString aLabels;
-  Standard_Integer anIndex = 1, aLen = aSTLMesh->Triangles().Length();
-  for ( ; anIndex <= aLen; anIndex++ ){
-    aLabels.Bind( anIndex, TCollection_AsciiString( anIndex ) );
-  }
 
-  Handle(MeshVS_TextPrsBuilder) aTextBuilder = new MeshVS_TextPrsBuilder( aMesh.operator->(), 20., Quantity_NOC_YELLOW );
-  aTextBuilder->SetTexts( Standard_True, aLabels );
-  aMesh->AddBuilder( aTextBuilder );
+  aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
 
   // Hide all nodes by default
   Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
-  aLen = aSTLMesh->Vertices().Length();
-  for ( anIndex = 1; anIndex <= aLen; anIndex++ )
+  Standard_Integer aLen = aSTLMesh->Nodes().Length();
+  for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
     aNodes->ChangeMap().Add( anIndex );
   aMesh->SetHiddenNodes( aNodes );
+  aMesh->SetSelectableNodes ( aNodes );
 
-  Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
-
-  if ( aContext.IsNull() )
-  {
-    ViewerTest::ViewerInit();
-    //To create a 3D view if it doesn't exist
-    aContext = ViewerTest::GetAISContext();
-    if( aContext.IsNull() )
-    {
-      di << "Cannot create 3D view" << "\n";
-      return 0;
-    }
-  }
-
-  aContext->Display( aMesh );
+  VDisplayAISObject(argv[1], aMesh);
   aContext->Deactivate( aMesh );
 
   Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
-  Handle( V3d_View ) V = ViewerTest::CurrentView();
-  if ( !V.IsNull() )
-    V->FitAll();
+  Handle( V3d_View ) aView = ViewerTest::CurrentView();
+  if ( !aView.IsNull() )
+    aView->FitAll();
 
   return 0;
 }
 //-----------------------------------------------------------------------------
-Handle( MeshVS_Mesh ) getMesh( const char* name, Draw_Interpretor& di)
-{
-  Handle( XSDRAWSTLVRML_DrawableMesh ) aDrawMesh =
-    Handle( XSDRAWSTLVRML_DrawableMesh )::DownCast( Draw::Get( name ) );
 
-  if( aDrawMesh.IsNull() )
+static Standard_Integer create3d
+(Draw_Interpretor& di, Standard_Integer argc, const char** argv )
+{
+  if (argc<2)
   {
-    di << "There is no such object" << "\n";
-    return NULL;
+    di << "Wrong number of parameters\n";
+    di << "Use: " << argv[0] << " <mesh name>\n";
+    return 0;
   }
-  else
+
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
   {
-    Handle( MeshVS_Mesh ) aMesh = aDrawMesh->GetMesh();
-    if( aMesh.IsNull() )
-    {
-      di << "There is invalid mesh" << "\n";
-      return NULL;
-    }
-    else
-      return aMesh;
+    di << "No active view. Please call 'vinit' first\n";
+    return 0;
   }
-}
-//-----------------------------------------------------------------------------
-static Standard_Integer meshdm
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv )
-{
-  if (argc<3)
-    di << "wrong number of parameters" << "\n";
-  else
-  {
-    Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
-    if( !aMesh.IsNull() )
-    {
-      Standard_Integer DisplayMode = 0;
-      sscanf( argv[2], "%i", &DisplayMode );
 
-      Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
+  Handle( XSDRAWSTLVRML_DataSource3D ) aDS = new XSDRAWSTLVRML_DataSource3D();
+  di << "Data source is created successful\n";
+  Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
+  di << "MeshVS_Mesh is created successful\n";
+
+  aMesh->SetDataSource( aDS );
+  aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
+
+  aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
+
+  // Hide all nodes by default
+  Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
+  Standard_Integer aLen = aDS->GetAllNodes().Extent();
+  for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
+    aNodes->ChangeMap().Add( anIndex );
+  aMesh->SetHiddenNodes( aNodes );
+  aMesh->SetSelectableNodes ( aNodes );
 
-      if( aContext.IsNull() )
-        di << "The context is null" << "\n";
-      else
-      {
-        Standard_Boolean HasLocal = aContext->HasOpenedContext();
-        if( HasLocal )
-          aContext->CloseLocalContext();
+  VDisplayAISObject(argv[1], aMesh);
+  aContext->Deactivate( aMesh );
 
-        aContext->SetDisplayMode( aMesh, DisplayMode );
-        di << "Setting display mode: " << DisplayMode << "\n";
+  Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
+  Handle( V3d_View ) aView = ViewerTest::CurrentView();
+  if ( !aView.IsNull() )
+    aView->FitAll();
 
-        if( HasLocal )
-          aContext->OpenLocalContext();
-      }
-    }
-  }
   return 0;
 }
-//-----------------------------------------------------------------------------
-static Standard_Integer meshsm
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv )
+
+Handle( MeshVS_Mesh ) getMesh( const char* theName, Draw_Interpretor& di)
 {
-  if (argc<3)
-    di << "wrong number of parameters" << "\n";
+  Handle( XSDRAWSTLVRML_DrawableMesh ) aDrawMesh =
+    Handle( XSDRAWSTLVRML_DrawableMesh )::DownCast( Draw::Get( theName ) );
+
+  if( aDrawMesh.IsNull() )
+  {
+    di << "There is no such object\n";
+    return NULL;
+  }
   else
   {
-    Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
-    if( !aMesh.IsNull() )
+    Handle( MeshVS_Mesh ) aMesh = aDrawMesh->GetMesh();
+    if( aMesh.IsNull() )
     {
-      Standard_Integer SelMode = 0;
-      sscanf( argv[2], "%i", &SelMode );
-
-      Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
-
-      if( aContext.IsNull() )
-        di << "The context is null" << "\n";
-      else
-      {
-        if( !aContext->HasOpenedContext() )
-          aContext->OpenLocalContext();
-
-        aContext->Load( aMesh, -1 );
-
-        if( SelMode==-1 )
-          aContext->CloseAllContexts();
-
-        else if( SelMode==0 )
-          aContext->Activate( aMesh, 0 );
-
-        else if( SelMode>0 )
-        {
-          aContext->Deactivate( aMesh, 0 );
-
-          if( SelMode & 1 )
-            aContext->Activate( aMesh, 1 );
-          else
-            aContext->Deactivate( aMesh, 1 );
-
-          if( SelMode & 4 )
-            aContext->Activate( aMesh, 4 );
-          else
-            aContext->Deactivate( aMesh, 4 );
-
-          if( SelMode & 8 )
-            aContext->Activate( aMesh, 8 );
-          else
-            aContext->Deactivate( aMesh, 8 );
-        }
-
-        di << "Setting selection mode: " << SelMode << "\n";
-      }
+      di << "There is invalid mesh\n";
+      return NULL;
     }
+    else
+      return aMesh;
   }
-  return 0;
 }
+
 //-----------------------------------------------------------------------------
 static Standard_Integer setcolor
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv, Standard_Integer Param )
+(Draw_Interpretor& di, Standard_Integer argc, const char** argv, Standard_Integer theParam )
 {
   if (argc<5)
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
   else
   {
     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
     if( !aMesh.IsNull() )
     {
-      Standard_Real r, g, b;
-      sscanf( argv[2], "%lf", &r );
-      sscanf( argv[3], "%lf", &g );
-      sscanf( argv[4], "%lf", &b );
-      aMesh->GetDrawer()->SetColor( (MeshVS_DrawerAttribute)Param, Quantity_Color( r, g, b, Quantity_TOC_RGB ) );
+      Standard_Real aRed = Draw::Atof (argv[2]);
+      Standard_Real aGreen = Draw::Atof (argv[3]);
+      Standard_Real aBlue = Draw::Atof (argv[4]);
+      aMesh->GetDrawer()->SetColor( (MeshVS_DrawerAttribute)theParam,
+                                    Quantity_Color( aRed, aGreen, aBlue, Quantity_TOC_RGB ) );
 
       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
 
       if( aContext.IsNull() )
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
       else
-        aContext->Redisplay( aMesh );
+        aContext->Redisplay (aMesh, Standard_True);
     }
   }
   return 0;
 }
 //-----------------------------------------------------------------------------
 static Standard_Integer meshcolor
-(Draw_Interpretor& interp, Standard_Integer argc, const char** argv )
+(Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
 {
-  return setcolor( interp, argc, argv, MeshVS_DA_InteriorColor );
+  return setcolor( theInterp, argc, argv, MeshVS_DA_InteriorColor );
 }
 //-----------------------------------------------------------------------------
 static Standard_Integer linecolor
-(Draw_Interpretor& interp, Standard_Integer argc, const char** argv )
+(Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
 {
-  return setcolor( interp, argc, argv, MeshVS_DA_EdgeColor );
+  return setcolor( theInterp, argc, argv, MeshVS_DA_EdgeColor );
 }
 //-----------------------------------------------------------------------------
 static Standard_Integer meshmat
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
   if (argc<3)
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
   else
   {
     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
     if( !aMesh.IsNull() )
     {
-      Standard_Integer mat;
-      sscanf( argv[2], "%i", &mat );
+      Standard_Integer aMaterial = Draw::Atoi (argv[2]);
 
       Graphic3d_MaterialAspect aMatAsp =
-        (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)mat;
+        (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)aMaterial;
 
+      if (argc == 4)
+      {
+        Standard_Real aTransparency = Draw::Atof(argv[3]);
+        aMatAsp.SetTransparency (Standard_ShortReal (aTransparency));
+      }
       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_FrontMaterial, aMatAsp );
       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_BackMaterial, aMatAsp );
 
       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
 
       if( aContext.IsNull() )
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
       else
-        aContext->Redisplay( aMesh );
+        aContext->Redisplay (aMesh, Standard_True);
     }
   }
   return 0;
@@ -477,33 +827,62 @@ static Standard_Integer shrink
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
   if (argc<3)
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
   else
   {
     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
     if( !aMesh.IsNull() )
     {
-      Standard_Real sh;
-      sscanf( argv[2], "%lf", &sh );
-      aMesh->GetDrawer()->SetDouble( MeshVS_DA_ShrinkCoeff, sh );
+      Standard_Real aShrinkCoeff = Draw::Atof (argv[2]);
+      aMesh->GetDrawer()->SetDouble( MeshVS_DA_ShrinkCoeff, aShrinkCoeff );
 
       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
 
       if( aContext.IsNull() )
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
+      else
+        aContext->Redisplay (aMesh, Standard_True);
+    }
+  }
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+static Standard_Integer closed (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
+{
+  if (theArgc < 3)
+  {
+    theDI << "Wrong number of parameters.\n";
+  }
+  else
+  {
+    Handle(MeshVS_Mesh) aMesh = getMesh (theArgv[1], theDI);
+    if (!aMesh.IsNull())
+    {
+      Standard_Boolean aFlag = Draw::Atoi (theArgv[2]) != 0;
+      aMesh->GetDrawer()->SetBoolean (MeshVS_DA_SupressBackFaces, aFlag);
+
+      Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
+      if (aContext.IsNull())
+      {
+        theDI << "The context is null\n";
+      }
       else
-        aContext->Redisplay( aMesh );
+      {
+        aContext->Redisplay (aMesh, Standard_True);
+      }
     }
   }
   return 0;
 }
+
 //-----------------------------------------------------------------------------
 
 static Standard_Integer mdisplay
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
   if (argc<2)
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
   else
   {
     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
@@ -512,13 +891,10 @@ static Standard_Integer mdisplay
       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
 
       if( aContext.IsNull() )
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
       else
       {
-        if( aContext->HasOpenedContext() )
-          aContext->CloseLocalContext();
-
-        aContext->Display( aMesh );
+        aContext->Display (aMesh, Standard_True);
       }
     }
   }
@@ -529,7 +905,7 @@ static Standard_Integer merase
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
   if (argc<2)
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
   else
   {
     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
@@ -538,17 +914,14 @@ static Standard_Integer merase
       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
 
       if( aContext.IsNull() )
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
       else
       {
-        if( aContext->HasOpenedContext() )
-          aContext->CloseLocalContext();
-
-        aContext->Erase( aMesh );
+        aContext->Erase (aMesh, Standard_True);
       }
     }
     else
-      di << "Mesh is null" << "\n";
+      di << "Mesh is null\n";
   }
   return 0;
 }
@@ -556,41 +929,55 @@ static Standard_Integer merase
 static Standard_Integer hidesel
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
-  if (argc<1)
+  if (argc<2)
   {
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
+    di << "Use: " << argv[0] << " <mesh name>\n";
     return 0;
   }
 
-
   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
   if( aMesh.IsNull() )
   {
-    di << "The mesh is invalid" << "\n";
+    di << "The mesh is invalid\n";
     return 0;
   }
 
   if( aContext.IsNull() )
-    di << "The context is null" << "\n";
+    di << "The context is null\n";
   else
   {
     Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = aMesh->GetHiddenNodes();
+    if (aHiddenNodes.IsNull())
+    {
+      aHiddenNodes = new TColStd_HPackedMapOfInteger();
+    }
     Handle(TColStd_HPackedMapOfInteger) aHiddenElements = aMesh->GetHiddenElems();
+    if (aHiddenElements.IsNull())
+    {
+      aHiddenElements = new TColStd_HPackedMapOfInteger();
+    }
     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
     {
       Handle( MeshVS_MeshEntityOwner ) anOwner =
         Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
       if( !anOwner.IsNull() )
+      {
         if( anOwner->Type()==MeshVS_ET_Node )
+        {
           aHiddenNodes->ChangeMap().Add( anOwner->ID() );
+        }
         else
+        {
           aHiddenElements->ChangeMap().Add( anOwner->ID() );
+        }
+      }
     }
-    aContext->ClearSelected();
+    aContext->ClearSelected (Standard_False);
     aMesh->SetHiddenNodes( aHiddenNodes );
     aMesh->SetHiddenElems( aHiddenElements );
-    aContext->Redisplay( aMesh );
+    aContext->Redisplay (aMesh, Standard_True);
   }
 
   return 0;
@@ -599,9 +986,10 @@ static Standard_Integer hidesel
 static Standard_Integer showonly
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
-  if (argc<1)
+  if (argc<2)
   {
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
+    di << "Use: " << argv[0] << " <mesh name>\n";
     return 0;
   }
 
@@ -610,12 +998,12 @@ static Standard_Integer showonly
   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
   if( aMesh.IsNull() )
   {
-    di << "The mesh is invalid" << "\n";
+    di << "The mesh is invalid\n";
     return 0;
   }
 
   if( aContext.IsNull() )
-    di << "The context is null" << "\n";
+    di << "The context is null\n";
   else
   {
     Handle(TColStd_HPackedMapOfInteger) aHiddenNodes =
@@ -627,14 +1015,20 @@ static Standard_Integer showonly
       Handle( MeshVS_MeshEntityOwner ) anOwner =
         Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
       if( !anOwner.IsNull() )
-        if( anOwner->Type()==MeshVS_ET_Node )
+      {
+        if( anOwner->Type() == MeshVS_ET_Node )
+        {
           aHiddenNodes->ChangeMap().Remove( anOwner->ID() );
+        }
         else
+        {
           aHiddenElements->ChangeMap().Remove( anOwner->ID() );
+        }
+      }
     }
     aMesh->SetHiddenNodes( aHiddenNodes );
     aMesh->SetHiddenElems( aHiddenElements );
-    aContext->Redisplay( aMesh );
+    aContext->Redisplay (aMesh, Standard_True);
   }
 
   return 0;
@@ -643,9 +1037,10 @@ static Standard_Integer showonly
 static Standard_Integer showall
 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
 {
-  if (argc<1)
+  if (argc<2)
   {
-    di << "wrong number of parameters" << "\n";
+    di << "Wrong number of parameters\n";
+    di << "Use: " << argv[0] << " <mesh name>\n";
     return 0;
   }
 
@@ -653,60 +1048,23 @@ static Standard_Integer showall
   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
   if( aMesh.IsNull() )
   {
-    di << "The mesh is invalid" << "\n";
+    di << "The mesh is invalid\n";
     return 0;
   }
 
   if( aContext.IsNull() )
-    di << "The context is null" << "\n";
+    di << "The context is null\n";
   else
   {
-    aMesh->SetHiddenNodes( 0 );
-    aMesh->SetHiddenElems( 0 );
-    aContext->Redisplay( aMesh );
+    aMesh->SetHiddenNodes( new TColStd_HPackedMapOfInteger() );
+    aMesh->SetHiddenElems( new TColStd_HPackedMapOfInteger() );
+    aContext->Redisplay (aMesh, Standard_True);
   }
 
   return 0;
 }
-//-----------------------------------------------------------------------------
-static Standard_Integer delmesh
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv )
-{
-  if (argc<2)
-  {
-    di << "wrong number of parameters" << "\n";
-    return 0;
-  }
 
-  Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
-
-  if( aMesh.IsNull() )
-  {
-    di << "The mesh is invalid" << "\n";
-    return 0;
-  }
-  else
-  {
-    Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
-
-    aContext->ClearSelected();
-
-    if( aContext->HasOpenedContext() )
-      aContext->CloseAllContexts();
-
-    aContext->Remove( aMesh );
-    aContext->SelectionManager()->Remove( aMesh );
-    aMesh->ClearSelections();
-    aContext->MainSelector()->Clear();
-
-    Draw::Set( argv[1], Handle(XSDRAWSTLVRML_DrawableMesh)() );
-
-    Standard::Purge();
-  }
-  return 0;
-}
 //-----------------------------------------------------------------------------
-
 static Standard_Integer meshcolors( Draw_Interpretor& di,
                                     Standard_Integer argc,
                                     const char** argv )
@@ -714,16 +1072,17 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
   try
   {
     OCC_CATCH_SIGNALS
-      if ( argc < 2 )
+      if ( argc < 4 )
       {
-        di << "Use : meshcolors meshname mode isreflect" << "\n";
-        di << "mode : {elem1|elem2|nodal|nodaltex|none}"<< "\n";
-        di << "       elem1 - different color for each element" << "\n";
-        di << "       elem2 - one color for one side"<<"\n";
-        di << "       nodal - different color for each node"<< "\n";
-        di << "       nodaltex - different color for each node with texture interpolation"<< "\n";
-        di << "       none  - clear"<< "\n";
-        di << "isreflect : {0|1} "<< "\n";
+        di << "Wrong number of parameters\n";
+        di << "Use : meshcolors <mesh name> <mode> <isreflect>\n";
+        di << "mode : {elem1|elem2|nodal|nodaltex|none}\n";
+        di << "       elem1 - different color for each element\n";
+        di << "       elem2 - one color for one side\n";
+        di << "       nodal - different color for each node\n";
+        di << "       nodaltex - different color for each node with texture interpolation\n";
+        di << "       none  - clear\n";
+        di << "isreflect : {0|1} \n";
 
         return 0;
       }
@@ -732,31 +1091,31 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
 
       if ( aMesh.IsNull() )
       {
-        di << "Mesh not found" << "\n";
+        di << "Mesh not found\n";
         return 0;
       }
       Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
       if ( anIC.IsNull() )
       {
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
         return 0;
       }
       if( !aMesh.IsNull() )
       {
         TCollection_AsciiString aMode = TCollection_AsciiString (argv[2]);
-        Quantity_Color aColor1( (Quantity_NameOfColor)( Quantity_NOC_BLUE1 ) );
-        Quantity_Color aColor2( (Quantity_NameOfColor)( Quantity_NOC_RED1 ) );
+        Quantity_Color aColor1(Quantity_NOC_BLUE1);
+        Quantity_Color aColor2(Quantity_NOC_RED1);
         if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") || aMode.IsEqual("nodal") || aMode.IsEqual("nodaltex") || aMode.IsEqual("none") )
         {
           Handle(MeshVS_PrsBuilder) aTempBuilder;
-          Standard_Integer reflection = atoi(argv[3]);
+          Standard_Integer aReflection = Draw::Atoi(argv[3]);
 
-          for (int count = 0 ; count < aMesh->GetBuildersCount(); count++ ){
-            aTempBuilder = Handle(MeshVS_PrsBuilder)::DownCast(aMesh->FindBuilder("MeshVS_ElementalColorPrsBuilder"));
+          for (Standard_Integer aCount = 0 ; aCount < aMesh->GetBuildersCount(); aCount++ ){
+            aTempBuilder = aMesh->FindBuilder("MeshVS_ElementalColorPrsBuilder");
             if( !aTempBuilder.IsNull())
               aMesh->RemoveBuilderById(aTempBuilder->GetId());
 
-            aTempBuilder = Handle(MeshVS_PrsBuilder)::DownCast(aMesh->FindBuilder("MeshVS_NodalColorPrsBuilder"));
+            aTempBuilder = aMesh->FindBuilder("MeshVS_NodalColorPrsBuilder");
             if( !aTempBuilder.IsNull())
               aMesh->RemoveBuilderById(aTempBuilder->GetId());
           }
@@ -844,7 +1203,7 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
               try {
                 OCC_CATCH_SIGNALS
                 aScaleValue = (aCoords.Value(1) - (Standard_Real) aMinX) / aDelta;
-              } catch(Standard_Failure) {
+              } catch(Standard_Failure const&) {
                 aScaleValue = 0;
               }
 
@@ -856,33 +1215,291 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
             aBuilder->SetInvalidColor(Quantity_NOC_BLACK);
             aBuilder->SetTextureCoords(aScaleMap);
             aMesh->AddBuilder(aBuilder, Standard_True);
-
-            //set viewer to display texures
-            const Handle(V3d_Viewer)& aViewer = anIC->CurrentViewer();
-            for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
-                 aViewer->ActiveView()->SetSurfaceDetail(V3d_TEX_ALL);
           }
 
-          aMesh->GetDrawer()->SetBoolean ( MeshVS_DA_ColorReflection, Standard_Boolean(reflection) );
+          aMesh->GetDrawer()->SetBoolean (MeshVS_DA_ColorReflection, aReflection != 0);
 
-          anIC->Redisplay( aMesh );
+          anIC->Redisplay (aMesh, Standard_True);
         }
         else
         {
-          di << "Wrong mode name" << "\n";
+          di << "Wrong mode name\n";
           return 0;
         }
       }
   }
-  catch ( Standard_Failure )
+  catch ( Standard_Failure const& )
+  {
+    di << "Error\n";
+  }
+
+  return 0;
+}
+//-----------------------------------------------------------------------------
+static Standard_Integer meshvectors( Draw_Interpretor& di,
+                                     Standard_Integer argc,
+                                     const char** argv )
+{
+  if ( argc < 3 )
+  {
+    di << "Wrong number of parameters\n";
+    di << "Use : meshvectors <mesh name> < -mode {elem|nodal|none} > [-maxlen len] [-color name] [-arrowpart ratio] [-issimple {1|0}]\n";
+    di << "Supported mode values:\n";
+    di << "       elem  - vector per element\n";
+    di << "       nodal - vector per node\n";
+    di << "       none  - clear\n";
+
+    return 0;
+  }
+
+  Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
+
+  if ( aMesh.IsNull() )
+  {
+    di << "Mesh not found\n";
+    return 0;
+  }
+  Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
+  if ( anIC.IsNull() )
+  {
+    di << "The context is null\n";
+    return 0;
+  }
+
+  TCollection_AsciiString aParam;
+  TCollection_AsciiString aMode("none");
+  Standard_Real           aMaxlen(1.0);
+  Quantity_Color          aColor(Quantity_NOC_ORANGE);
+  Standard_Real           anArrowPart(0.1);
+  Standard_Boolean        isSimplePrs(Standard_False);
+
+  for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
+  {
+    if (!aParam.IsEmpty())
+    {
+      if (aParam == "-mode")
+      {
+        aMode       = argv[anIdx];
+      }
+      else if (aParam == "-maxlen")
+      {
+        aMaxlen     = Draw::Atof(argv[anIdx]);
+      }
+      else if (aParam == "-color")
+      {
+        aColor      = ViewerTest::GetColorFromName(argv[anIdx]);
+      }
+      else if (aParam == "-arrowpart")
+      {
+        anArrowPart = Draw::Atof(argv[anIdx]);
+      }
+      else if (aParam == "-issimple")
+      {
+        isSimplePrs = Draw::Atoi(argv[anIdx]) != 0;
+      }
+      aParam.Clear();
+    }
+    else if (argv[anIdx][0] == '-')
+    {
+      aParam = argv[anIdx];
+    }
+  }
+
+  if( !aMode.IsEqual("elem") && !aMode.IsEqual("nodal") && !aMode.IsEqual("none") )
+  {
+    di << "Wrong mode name\n";
+    return 0;
+  }
+
+  Handle(MeshVS_PrsBuilder) aTempBuilder;
+
+  aTempBuilder = aMesh->FindBuilder("MeshVS_VectorPrsBuilder");
+  if( !aTempBuilder.IsNull())
+    aMesh->RemoveBuilderById(aTempBuilder->GetId());
+
+  if( !aMode.IsEqual("none") )
   {
-    di << "Error" << "\n";
+    Handle(MeshVS_VectorPrsBuilder) aBuilder = new MeshVS_VectorPrsBuilder( aMesh.operator->(), 
+                                                                            aMaxlen,
+                                                                            aColor,
+                                                                            MeshVS_DMF_VectorDataPrs,
+                                                                            0,
+                                                                            -1,
+                                                                            MeshVS_BP_Vector,
+                                                                            isSimplePrs);
+
+    Standard_Boolean anIsElement = aMode.IsEqual("elem");
+    const TColStd_PackedMapOfInteger& anAllIDs = anIsElement ? aMesh->GetDataSource()->GetAllElements() :
+                                                               aMesh->GetDataSource()->GetAllNodes();
+
+    Standard_Integer aNbNodes;
+    MeshVS_EntityType aEntType;
+
+    TColStd_Array1OfReal aCoords(1, 3);
+    aCoords.Init (0.);
+    TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
+    for ( ; anIter.More(); anIter.Next() )
+    {
+      Standard_Boolean IsValidData = Standard_False; 
+      if (anIsElement) {
+        aMesh->GetDataSource()->GetGeomType(anIter.Key(), anIsElement, aEntType);
+        if (aEntType == MeshVS_ET_Face)
+          IsValidData = aMesh->GetDataSource()->GetNormal(anIter.Key(), 3, aCoords.ChangeValue(1), aCoords.ChangeValue(2), aCoords.ChangeValue(3));
+      } else
+        IsValidData = aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
+
+      gp_Vec aNorm;
+      if(IsValidData)
+      { 
+        aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
+        if(aNorm.Magnitude() < gp::Resolution())
+        {
+          aNorm = gp_Vec(0,0,1); //method GetGeom(...) returns coordinates of nodes
+        }
+      }
+      else
+      {
+        aNorm = gp_Vec(0,0,1);
+      }
+      aBuilder->SetVector(anIsElement, anIter.Key(), aNorm.Normalized());
+    }
+
+    aMesh->AddBuilder( aBuilder, Standard_False );
+    aMesh->GetDrawer()->SetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart );
   }
 
+  anIC->Redisplay (aMesh, Standard_True);
+
   return 0;
 }
 //-----------------------------------------------------------------------------
 
+static Standard_Integer meshtext( Draw_Interpretor& di,
+                                  Standard_Integer argc,
+                                  const char** argv )
+{
+  if ( argc < 2 )
+  {
+    di << "Wrong number of parameters\n";
+    di << "Use : meshtext <mesh name>\n";
+    return 0;
+  }
+
+  Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
+
+  if ( aMesh.IsNull() )
+  {
+    di << "Mesh not found\n";
+    return 0;
+  }
+
+  Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
+  if ( anIC.IsNull() )
+  {
+    di << "The context is null\n";
+    return 0;
+  }
+
+  // Prepare triangle labels
+  MeshVS_DataMapOfIntegerAsciiString aLabels;
+  Standard_Integer aLen = aMesh->GetDataSource()->GetAllElements().Extent();
+  for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ ){
+    aLabels.Bind( anIndex, TCollection_AsciiString( anIndex ) );
+  }
+
+  Handle(MeshVS_TextPrsBuilder) aTextBuilder = new MeshVS_TextPrsBuilder( aMesh.operator->(), 20., Quantity_NOC_YELLOW );
+  aTextBuilder->SetTexts( Standard_True, aLabels );
+  aMesh->AddBuilder( aTextBuilder );
+
+  return 0;
+}
+
+static Standard_Integer meshdeform( Draw_Interpretor& di,
+                                    Standard_Integer argc,
+                                    const char** argv )
+{
+  if ( argc < 3 )
+  {
+    di << "Wrong number of parameters\n";
+    di << "Use : meshdeform <mesh name> < -mode {on|off} > [-scale scalefactor]\n";
+    return 0;
+  }
+
+  Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
+
+  if ( aMesh.IsNull() )
+  {
+    di << "Mesh not found\n";
+    return 0;
+  }
+  Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
+  if ( anIC.IsNull() )
+  {
+    di << "The context is null\n";
+    return 0;
+  }
+
+  TCollection_AsciiString aParam;
+  TCollection_AsciiString aMode("off");
+  Standard_Real           aScale(1.0);
+
+  for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
+  {
+    if (!aParam.IsEmpty())
+    {
+      if (aParam == "-mode")
+      {
+        aMode = argv[anIdx];
+      }
+      else if (aParam == "-scale")
+      {
+        aScale = Draw::Atof(argv[anIdx]);
+      }
+      aParam.Clear();
+    }
+    else if (argv[anIdx][0] == '-')
+    {
+      aParam = argv[anIdx];
+    }
+  }
+
+  if(!aMode.IsEqual("on") && !aMode.IsEqual("off"))
+  {
+    di << "Wrong mode name\n";
+    return 0;
+  }
+
+  Handle ( MeshVS_DeformedDataSource ) aDefDS =
+    new MeshVS_DeformedDataSource( aMesh->GetDataSource() , aScale );
+
+  const TColStd_PackedMapOfInteger& anAllIDs = aMesh->GetDataSource()->GetAllNodes();
+
+  Standard_Integer aNbNodes;
+  MeshVS_EntityType aEntType;
+
+  TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
+  for ( ; anIter.More(); anIter.Next() )
+  {
+    TColStd_Array1OfReal aCoords(1, 3);
+    aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
+
+    gp_Vec aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
+    if( !aNorm.Magnitude() )
+      aNorm = gp_Vec(0,0,1);
+    aDefDS->SetVector(anIter.Key(), aNorm.Normalized());
+  }
+
+  aMesh->SetDataSource(aDefDS);
+
+  anIC->Redisplay (aMesh, Standard_False);
+
+  Handle( V3d_View ) aView = ViewerTest::CurrentView();
+  if ( !aView.IsNull() )
+    aView->FitAll();
+
+  return 0;
+}
+
 static Standard_Integer mesh_edge_width( Draw_Interpretor& di,
                                         Standard_Integer argc,
                                         const char** argv )
@@ -892,46 +1509,79 @@ static Standard_Integer mesh_edge_width( Draw_Interpretor& di,
     OCC_CATCH_SIGNALS
       if ( argc < 3 )
       {
-        di << "Wrong number of parameters. Use : mesh_edge_width mesh width" << "\n";
+        di << "Wrong number of parameters\n";
+        di << "Use : mesh_edge_width <mesh name> <width>\n";
         return 0;
       }
 
       Handle(MeshVS_Mesh) aMesh = getMesh( argv[ 1 ], di );
       if ( aMesh.IsNull() )
       {
-        di << "Mesh not found" << "\n";
+        di << "Mesh not found\n";
         return 0;
       }
 
       const char* aWidthStr = argv[ 2 ];
-      if ( aWidthStr == 0 || atof( aWidthStr ) <= 0 )
+      if ( aWidthStr == 0 || Draw::Atof( aWidthStr ) <= 0 )
       {
-        di << "Width must be real value more than zero" << "\n";
+        di << "Width must be real value more than zero\n";
         return 0;
       }
 
-      double aWidth = atof( aWidthStr );
+      double aWidth = Draw::Atof( aWidthStr );
 
       Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
       if ( anIC.IsNull() )
       {
-        di << "The context is null" << "\n";
+        di << "The context is null\n";
         return 0;
       }
 
       Handle(MeshVS_Drawer) aDrawer = aMesh->GetDrawer();
       if ( aDrawer.IsNull() )
       {
-        di << "The drawer is null" << "\n";
+        di << "The drawer is null\n";
         return 0;
       }
 
       aDrawer->SetDouble( MeshVS_DA_EdgeWidth, aWidth );
-      anIC->Redisplay( aMesh );
+      anIC->Redisplay (aMesh, Standard_True);
+  }
+  catch ( Standard_Failure const& )
+  {
+    di << "Error\n";
   }
-  catch ( Standard_Failure )
+
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+static Standard_Integer meshinfo(Draw_Interpretor& di,
+                                 Standard_Integer argc,
+                                 const char** argv)
+{
+  if ( argc != 2 )
+  {
+    di << "Wrong number of parameters. Use : meshinfo mesh\n";
+    return 0;
+  }
+
+  Handle(MeshVS_Mesh) aMesh = getMesh(argv[ 1 ], di);
+  if ( aMesh.IsNull() )
+  {
+    di << "Mesh not found\n";
+    return 0;
+  }
+
+  Handle(XSDRAWSTLVRML_DataSource) stlMeshSource = Handle(XSDRAWSTLVRML_DataSource)::DownCast(aMesh->GetDataSource());
+  if (!stlMeshSource.IsNull())
   {
-    di << "Error" << "\n";
+    const TColStd_PackedMapOfInteger& nodes = stlMeshSource->GetAllNodes();
+    const TColStd_PackedMapOfInteger& tris  = stlMeshSource->GetAllElements();
+
+    di << "Nb nodes = " << nodes.Extent() << "\n";
+    di << "Nb triangles = " << tris.Extent() << "\n";
   }
 
   return 0;
@@ -944,27 +1594,63 @@ void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
   const char* g = "XSTEP-STL/VRML";  // Step transfer file commands
   //XSDRAW::LoadDraw(theCommands);
 
-  theCommands.Add ("writevrml", "shape file",__FILE__,writevrml,g);
-  theCommands.Add ("writestl",  "shape file",__FILE__,writestl,g);
-  theCommands.Add ("readstl",   "shape file",__FILE__,readstl,g);
+  theCommands.Add ("ReadGltf",
+                   "ReadGltf Doc file [-parallel {on|off}] [-listExternalFiles] [-noCreateDoc]"
+                   "\n\t\t: Read glTF file into XDE document."
+                   "\n\t\t:   -listExternalFiles do not read mesh and only list external files"
+                   "\n\t\t:   -noCreateDoc read into existing XDE document",
+                   __FILE__, ReadGltf, g);
+  theCommands.Add ("readgltf",
+                   "readgltf shape file"
+                   "\n\t\t: Same as ReadGltf but reads glTF file into a shape instead of a document.",
+                   __FILE__, ReadGltf, g);
+  theCommands.Add ("writevrml", "shape file [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 1 by default]",__FILE__,writevrml,g);
+  theCommands.Add ("writestl",  "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,g);
+  theCommands.Add ("readstl",
+                   "readstl shape file [-brep]"
+                   "\n\t\t: Reads STL file and creates a new shape with specified name."
+                   "\n\t\t: When -brep is specified, creates a Compound of per-triangle Faces."
+                   "\n\t\t: Single triangulation-only Face is created otherwise (default).",
+                   __FILE__, readstl, g);
   theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
-  theCommands.Add ("storevrml" , "shape file defl [type]",__FILE__,storevrml,g);
-
-  theCommands.Add ("meshfromstl",   "creates MeshVS_Mesh from STL file",  __FILE__, createmesh, g );
-  theCommands.Add ("meshdispmode",  "changes MeshVS_Mesh display mode",   __FILE__, meshdm,     g );
-  theCommands.Add ("meshselmode",   "changes MeshVS_Mesh selection mode", __FILE__, meshsm,     g );
-  theCommands.Add ("meshshadcolor", "change MeshVS_Mesh shading color",   __FILE__, meshcolor,  g );
-  theCommands.Add ("meshlinkcolor", "change MeshVS_Mesh line color",      __FILE__, linecolor,  g );
-  theCommands.Add ("meshmat",       "change MeshVS_Mesh material",        __FILE__, meshmat,    g );
-  theCommands.Add ("meshshrcoef",   "change MeshVS_Mesh shrink coeff",    __FILE__, shrink,     g );
-  theCommands.Add ("meshshow",      "display MeshVS_Mesh object",         __FILE__, mdisplay,   g );
-  theCommands.Add ("meshhide",      "erase MeshVS_Mesh object",           __FILE__, merase,     g );
-  theCommands.Add ("meshhidesel",   "hide selected entities",             __FILE__, hidesel,    g );
-  theCommands.Add ("meshshowsel",   "show only selected entities",        __FILE__, showonly,   g );
-  theCommands.Add ("meshshowall",   "show all entities",                  __FILE__, showall,    g );
-  theCommands.Add ("meshdelete",    "delete MeshVS_Mesh object",          __FILE__, delmesh,    g );
-  theCommands.Add ("meshcolors",    "display color presentation",         __FILE__, meshcolors, g );
-  theCommands.Add ("mesh_edge_width", "set width of edges",               __FILE__, mesh_edge_width, g );
+  theCommands.Add ("ReadObj",
+                   "ReadObj Doc file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
+           "\n\t\t:                  [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
+           "\n\t\t:                  [-listExternalFiles] [-noCreateDoc]"
+           "\n\t\t: Read OBJ file into XDE document."
+           "\n\t\t:   -fileUnit       length unit of OBJ file content;"
+           "\n\t\t:   -fileCoordSys   coordinate system defined by OBJ file; Yup when not specified."
+           "\n\t\t:   -resultCoordSys result coordinate system; Zup when not specified."
+           "\n\t\t:   -singlePrecision truncate vertex data to single precision during read; FALSE by default."
+           "\n\t\t:   -listExternalFiles do not read mesh and only list external files."
+           "\n\t\t:   -noCreateDoc    read into existing XDE document.",
+                   __FILE__, ReadObj, g);
+  theCommands.Add ("readobj",
+                   "readobj shape file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
+           "\n\t\t:                    [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
+           "\n\t\t:                    [-singleFace]"
+           "\n\t\t: Same as ReadObj but reads OBJ file into a shape instead of a document."
+           "\n\t\t:   -singleFace merge OBJ content into a single triangulation Face.",
+           __FILE__, ReadObj, g);
+
+  theCommands.Add ("meshfromstl",     "creates MeshVS_Mesh from STL file",            __FILE__, createmesh,      g );
+  theCommands.Add ("mesh3delem",      "creates 3d element mesh to test",              __FILE__, create3d,        g );
+  theCommands.Add ("meshshadcolor",   "change MeshVS_Mesh shading color",             __FILE__, meshcolor,       g );
+  theCommands.Add ("meshlinkcolor",   "change MeshVS_Mesh line color",                __FILE__, linecolor,       g );
+  theCommands.Add ("meshmat",         "change MeshVS_Mesh material and transparency", __FILE__, meshmat,         g );
+  theCommands.Add ("meshshrcoef",     "change MeshVS_Mesh shrink coeff",              __FILE__, shrink,          g );
+  theCommands.Add ("meshclosed",      "meshclosed meshname (0/1) \nChange MeshVS_Mesh drawing mode. 0 - not closed object, 1 - closed object", __FILE__, closed, g);
+  theCommands.Add ("meshshow",        "display MeshVS_Mesh object",                   __FILE__, mdisplay,        g );
+  theCommands.Add ("meshhide",        "erase MeshVS_Mesh object",                     __FILE__, merase,          g );
+  theCommands.Add ("meshhidesel",     "hide selected entities",                       __FILE__, hidesel,         g );
+  theCommands.Add ("meshshowsel",     "show only selected entities",                  __FILE__, showonly,        g );
+  theCommands.Add ("meshshowall",     "show all entities",                            __FILE__, showall,         g );
+  theCommands.Add ("meshcolors",      "display color presentation",                   __FILE__, meshcolors,      g );
+  theCommands.Add ("meshvectors",     "display sample vectors",                       __FILE__, meshvectors,     g );
+  theCommands.Add ("meshtext",        "display text labels",                          __FILE__, meshtext,        g );
+  theCommands.Add ("meshdeform",      "display deformed mesh",                        __FILE__, meshdeform,      g );
+  theCommands.Add ("mesh_edge_width", "set width of edges",                           __FILE__, mesh_edge_width, g );
+  theCommands.Add ("meshinfo",        "displays the number of nodes and triangles",   __FILE__, meshinfo,        g );
 }
 
 //==============================================================================
@@ -977,10 +1663,9 @@ void XSDRAWSTLVRML::Factory(Draw_Interpretor& theDI)
   XSDRAWIGES::InitFromBRep(theDI);
   XSDRAWSTEP::InitCommands(theDI);
   XSDRAWSTLVRML::InitCommands(theDI);
-  SWDRAW::Init(theDI);
   XSDRAW::LoadDraw(theDI);
-#ifdef DEB
-  theDI << "Draw Plugin : All TKXSDRAW commands are loaded" << "\n";
+#ifdef OCCT_DEBUG
+  theDI << "Draw Plugin : All TKXSDRAW commands are loaded\n";
 #endif
 }