0030180: Data Exchange - VrmlAPI_Writer is expected to return export state
[occt.git] / src / XSDRAWSTLVRML / XSDRAWSTLVRML.cxx
index b0ac14a..cf86dc0 100644 (file)
 #include <AIS_InteractiveContext.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 <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 <StlMesh_Mesh.hxx>
-#include <StlMesh_SequenceOfMeshTriangle.hxx>
 #include <TColgp_SequenceOfXYZ.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HPackedMapOfInteger.hxx>
 #include <TColStd_MapIteratorOfPackedMapOfInteger.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 <XSDRAWSTLVRML_DataSource3D.hxx>
 #include <XSDRAWSTLVRML_DrawableMesh.hxx>
 
-// avoid warnings on 'extern "C"' functions returning C++ classes
-#ifdef _MSC_VER
-#pragma warning(4:4190)
-#endif
-
 #ifndef _STDIO_H
 #include <stdio.h>
 #endif
@@ -81,6 +85,126 @@ extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theNam
                                            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)
 {
@@ -95,26 +219,279 @@ static Standard_Integer writestl
     }
     StlAPI_Writer aWriter;
     aWriter.ASCIIMode() = isASCIIMode;
-    StlAPI_ErrorStatus aStatus = aWriter.Write (aShape, argv[2]);
+    Standard_Boolean isOK = aWriter.Write (aShape, argv[2]);
+    if (!isOK)
+       di << "** Error **: Mesh writing has been failed.\n";
+  }
+  return 0;
+}
 
-    switch (aStatus)
+//=============================================================================
+//function : readstl
+//purpose  : Reads stl file
+//=============================================================================
+static Standard_Integer readstl(Draw_Interpretor& theDI,
+                                Standard_Integer theArgc,
+                                const char** theArgv)
+{
+  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")
     {
-    case StlAPI_MeshIsEmpty: di << "** Error **: Mesh is empty. Please, compute triangulation before."; break;
-    case StlAPI_CannotOpenFile: di << "** Error **: Cannot create/open a file with the passed name."; break;
-    case StlAPI_StatusOK: default: break;
+      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;
 }
 
-static Standard_Integer readstl
-(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+//! Parse RWMesh_CoordinateSystem enumeration.
+static Standard_Boolean parseCoordinateSystem (const char* theArg,
+                                               RWMesh_CoordinateSystem& theSystem)
 {
-  if (argc<3) di << "wrong number of parameters"    << "\n";
-  else {
-    TopoDS_Shape aShape ;
-    StlAPI::Read(aShape,argv[2]);
-    DBRep::Set(argv[1],aShape);
+  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;
 }
@@ -155,7 +532,10 @@ static Standard_Integer writevrml
   case 2: writer.SetRepresentation(VrmlAPI_BothRepresentation); break;
   }
 
-  writer.Write(aShape, argv[2], aVersion);
+  if (!writer.Write(aShape, argv[2], aVersion))
+  {
+    di << "Error: File " << argv[2] << " was not written\n";
+  }
 
   return 0;
 }
@@ -174,10 +554,10 @@ static Standard_Integer loadvrml
     VrmlData_DataMapOfShapeAppearance aShapeAppMap;
 
     //-----------------------------------------------------------
-    filebuf aFic;
-    istream aStream (&aFic);
+    std::filebuf aFic;
+    std::istream aStream (&aFic);
 
-    if (aFic.open(argv[2], ios::in)) {
+    if (aFic.open(argv[2], std::ios::in)) {
 
       // Get path of the VRML file.
       OSD_Path aPath(argv[2]);
@@ -195,6 +575,8 @@ static Standard_Integer loadvrml
       }
 
       VrmlData_Scene aScene;
+      Standard_Real anOCCUnit = UnitsMethods::GetCasCadeLengthUnit();
+      aScene.SetLinearScale(1000. / anOCCUnit);
 
       aScene.SetVrmlDir (aVrmlDir);
       aScene << aStream;
@@ -265,7 +647,7 @@ static Standard_Integer createmesh
   // 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";
   Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
@@ -280,7 +662,7 @@ static Standard_Integer createmesh
 
   // Hide all nodes by default
   Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
-  Standard_Integer aLen = aSTLMesh->Vertices().Length();
+  Standard_Integer aLen = aSTLMesh->Nodes().Length();
   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
     aNodes->ChangeMap().Add( anIndex );
   aMesh->SetHiddenNodes( aNodes );
@@ -389,7 +771,7 @@ static Standard_Integer setcolor
       if( aContext.IsNull() )
         di << "The context is null\n";
       else
-        aContext->Redisplay( aMesh );
+        aContext->Redisplay (aMesh, Standard_True);
     }
   }
   return 0;
@@ -425,7 +807,7 @@ static Standard_Integer meshmat
       if (argc == 4)
       {
         Standard_Real aTransparency = Draw::Atof(argv[3]);
-        aMatAsp.SetTransparency(aTransparency);
+        aMatAsp.SetTransparency (Standard_ShortReal (aTransparency));
       }
       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_FrontMaterial, aMatAsp );
       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_BackMaterial, aMatAsp );
@@ -435,7 +817,7 @@ static Standard_Integer meshmat
       if( aContext.IsNull() )
         di << "The context is null\n";
       else
-        aContext->Redisplay( aMesh );
+        aContext->Redisplay (aMesh, Standard_True);
     }
   }
   return 0;
@@ -459,7 +841,7 @@ static Standard_Integer shrink
       if( aContext.IsNull() )
         di << "The context is null\n";
       else
-        aContext->Redisplay( aMesh );
+        aContext->Redisplay (aMesh, Standard_True);
     }
   }
   return 0;
@@ -477,7 +859,7 @@ static Standard_Integer closed (Draw_Interpretor& theDI, Standard_Integer theArg
     Handle(MeshVS_Mesh) aMesh = getMesh (theArgv[1], theDI);
     if (!aMesh.IsNull())
     {
-      Standard_Integer aFlag = Draw::Atoi (theArgv[2]);
+      Standard_Boolean aFlag = Draw::Atoi (theArgv[2]) != 0;
       aMesh->GetDrawer()->SetBoolean (MeshVS_DA_SupressBackFaces, aFlag);
 
       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
@@ -487,7 +869,7 @@ static Standard_Integer closed (Draw_Interpretor& theDI, Standard_Integer theArg
       }
       else
       {
-        aContext->Redisplay (aMesh);
+        aContext->Redisplay (aMesh, Standard_True);
       }
     }
   }
@@ -512,10 +894,7 @@ static Standard_Integer mdisplay
         di << "The context is null\n";
       else
       {
-        if( aContext->HasOpenedContext() )
-          aContext->CloseLocalContext();
-
-        aContext->Display( aMesh );
+        aContext->Display (aMesh, Standard_True);
       }
     }
   }
@@ -538,10 +917,7 @@ static Standard_Integer merase
         di << "The context is null\n";
       else
       {
-        if( aContext->HasOpenedContext() )
-          aContext->CloseLocalContext();
-
-        aContext->Erase( aMesh );
+        aContext->Erase (aMesh, Standard_True);
       }
     }
     else
@@ -598,10 +974,10 @@ static Standard_Integer hidesel
         }
       }
     }
-    aContext->ClearSelected();
+    aContext->ClearSelected (Standard_False);
     aMesh->SetHiddenNodes( aHiddenNodes );
     aMesh->SetHiddenElems( aHiddenElements );
-    aContext->Redisplay( aMesh );
+    aContext->Redisplay (aMesh, Standard_True);
   }
 
   return 0;
@@ -652,7 +1028,7 @@ static Standard_Integer showonly
     }
     aMesh->SetHiddenNodes( aHiddenNodes );
     aMesh->SetHiddenElems( aHiddenElements );
-    aContext->Redisplay( aMesh );
+    aContext->Redisplay (aMesh, Standard_True);
   }
 
   return 0;
@@ -682,7 +1058,7 @@ static Standard_Integer showall
   {
     aMesh->SetHiddenNodes( new TColStd_HPackedMapOfInteger() );
     aMesh->SetHiddenElems( new TColStd_HPackedMapOfInteger() );
-    aContext->Redisplay( aMesh );
+    aContext->Redisplay (aMesh, Standard_True);
   }
 
   return 0;
@@ -727,19 +1103,19 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
       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 aReflection = Draw::Atoi(argv[3]);
 
           for (Standard_Integer aCount = 0 ; aCount < aMesh->GetBuildersCount(); aCount++ ){
-            aTempBuilder = Handle(MeshVS_PrsBuilder)::DownCast(aMesh->FindBuilder("MeshVS_ElementalColorPrsBuilder"));
+            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());
           }
@@ -827,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;
               }
 
@@ -839,16 +1215,11 @@ 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(aReflection) );
+          aMesh->GetDrawer()->SetBoolean (MeshVS_DA_ColorReflection, aReflection != 0);
 
-          anIC->Redisplay( aMesh );
+          anIC->Redisplay (aMesh, Standard_True);
         }
         else
         {
@@ -857,7 +1228,7 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
         }
       }
   }
-  catch ( Standard_Failure )
+  catch ( Standard_Failure const& )
   {
     di << "Error\n";
   }
@@ -924,7 +1295,7 @@ static Standard_Integer meshvectors( Draw_Interpretor& di,
       }
       else if (aParam == "-issimple")
       {
-        isSimplePrs = Draw::Atoi(argv[anIdx]);
+        isSimplePrs = Draw::Atoi(argv[anIdx]) != 0;
       }
       aParam.Clear();
     }
@@ -942,7 +1313,7 @@ static Standard_Integer meshvectors( Draw_Interpretor& di,
 
   Handle(MeshVS_PrsBuilder) aTempBuilder;
 
-  aTempBuilder = Handle(MeshVS_PrsBuilder)::DownCast(aMesh->FindBuilder("MeshVS_VectorPrsBuilder"));
+  aTempBuilder = aMesh->FindBuilder("MeshVS_VectorPrsBuilder");
   if( !aTempBuilder.IsNull())
     aMesh->RemoveBuilderById(aTempBuilder->GetId());
 
@@ -964,18 +1335,32 @@ static Standard_Integer meshvectors( Draw_Interpretor& di,
     Standard_Integer aNbNodes;
     MeshVS_EntityType aEntType;
 
+    TColStd_Array1OfReal aCoords(1, 3);
+    aCoords.Init (0.);
     TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
     for ( ; anIter.More(); anIter.Next() )
     {
-      TColStd_Array1OfReal aCoords(1, 3);
-      if (anIsElement)
-        aMesh->GetDataSource()->GetNormal(anIter.Key(), 3, aCoords.ChangeValue(1), aCoords.ChangeValue(2), aCoords.ChangeValue(3));
+      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
-        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);
+      }
       aBuilder->SetVector(anIsElement, anIter.Key(), aNorm.Normalized());
     }
 
@@ -983,7 +1368,7 @@ static Standard_Integer meshvectors( Draw_Interpretor& di,
     aMesh->GetDrawer()->SetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart );
   }
 
-  anIC->Redisplay( aMesh );
+  anIC->Redisplay (aMesh, Standard_True);
 
   return 0;
 }
@@ -1106,7 +1491,7 @@ static Standard_Integer meshdeform( Draw_Interpretor& di,
 
   aMesh->SetDataSource(aDefDS);
 
-  anIC->Redisplay( aMesh );
+  anIC->Redisplay (aMesh, Standard_False);
 
   Handle( V3d_View ) aView = ViewerTest::CurrentView();
   if ( !aView.IsNull() )
@@ -1160,9 +1545,9 @@ static Standard_Integer mesh_edge_width( Draw_Interpretor& di,
       }
 
       aDrawer->SetDouble( MeshVS_DA_EdgeWidth, aWidth );
-      anIC->Redisplay( aMesh );
+      anIC->Redisplay (aMesh, Standard_True);
   }
-  catch ( Standard_Failure )
+  catch ( Standard_Failure const& )
   {
     di << "Error\n";
   }
@@ -1209,10 +1594,44 @@ void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
   const char* g = "XSTEP-STL/VRML";  // Step transfer file commands
   //XSDRAW::LoadDraw(theCommands);
 
+  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",   "shape file",__FILE__,readstl,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 ("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 );