]> OCCT Git - occt.git/commitdiff
0032820: Data Exchange - add VRML reader to XCAF document
authoratychini <atychini@opencascade.com>
Tue, 12 Jul 2022 20:48:02 +0000 (23:48 +0300)
committersmoskvin <smoskvin@opencascade.com>
Fri, 23 Sep 2022 15:30:08 +0000 (18:30 +0300)
Implementing VRML reader into XCAF document.
Updating DE_Wrapper according to VRML Reader.

17 files changed:
src/TKVRML/EXTERNLIB
src/Vrml/Vrml_ConfigurationNode.cxx
src/Vrml/Vrml_ConfigurationNode.hxx
src/Vrml/Vrml_Provider.cxx
src/VrmlAPI/FILES
src/VrmlAPI/VrmlAPI_CafReader.cxx [new file with mode: 0644]
src/VrmlAPI/VrmlAPI_CafReader.hxx [new file with mode: 0644]
src/XDEDRAW/XDEDRAW_Common.cxx
tests/de_mesh/grids.list
tests/de_mesh/vrml_read/A1 [new file with mode: 0644]
tests/de_mesh/vrml_read/A2 [new file with mode: 0644]
tests/de_mesh/vrml_read/A3 [new file with mode: 0644]
tests/de_mesh/vrml_read/A4 [new file with mode: 0644]
tests/de_mesh/vrml_read/begin [new file with mode: 0644]
tests/de_wrapper/configuration/A3
tests/de_wrapper/vrml/A5
tests/de_wrapper/vrml/A6

index b267b66d9d5eb42cd4de1b33b5e8e8b74df57460..a996dc40ca6a4db2662153da4dd7f44524d24495 100755 (executable)
@@ -9,6 +9,7 @@ TKG2d
 TKG3d
 TKMesh
 TKHLR
+TKRWMesh
 TKService
 TKGeomAlgo
 TKV3d
index d04fcebc330ed59769d685059deb6a8b5882d445..97c729d6f9e147189a1500c352ed08050fad265f 100644 (file)
@@ -56,6 +56,15 @@ bool Vrml_ConfigurationNode::Load(const Handle(DE_ConfigurationContext)& theReso
 {
   TCollection_AsciiString aScope = THE_CONFIGURATION_SCOPE() + "." + GetFormat() + "." + GetVendor();
 
+  InternalParameters.ReadFileUnit = 
+    theResource->RealVal("read.file.unit", InternalParameters.ReadFileUnit, aScope);
+  InternalParameters.ReadFileCoordinateSys = (RWMesh_CoordinateSystem)
+    theResource->IntegerVal("read.file.coordinate.system", InternalParameters.ReadFileCoordinateSys, aScope);
+  InternalParameters.ReadSystemCoordinateSys = (RWMesh_CoordinateSystem)
+    theResource->IntegerVal("read.system.coordinate.system", InternalParameters.ReadSystemCoordinateSys, aScope);
+  InternalParameters.ReadFillIncomplete =
+    theResource->BooleanVal("read.fill.incomplete", InternalParameters.ReadFillIncomplete, aScope);
+
   InternalParameters.WriterVersion = (WriteMode_WriterVersion)
     theResource->IntegerVal("writer.version", InternalParameters.WriterVersion, aScope);
   InternalParameters.WriteRepresentationType = (WriteMode_RepresentationType)
@@ -75,19 +84,47 @@ TCollection_AsciiString Vrml_ConfigurationNode::Save() const
   aResult = aResult + "!Configuration Node " + " Vendor: " + GetVendor() + " Format: " + GetFormat() + "\n";
   TCollection_AsciiString aScope = THE_CONFIGURATION_SCOPE() + "." + GetFormat() + "." + GetVendor() + ".";
 
+  aResult += "!\n";
+  aResult += "!Read parameters:\n";
+  aResult += "!\n";
+
+  aResult += "!\n";
+  aResult += "!Set (override) file length units to convert from while reading the file, defined as scale factor for m (meters).\n";
+  aResult += "!Default value: 1. Available values: positive double\n";
+  aResult += aScope + "read.file.unit :\t " + InternalParameters.ReadFileUnit + "\n";
+  aResult += "!\n";
+
+  aResult += "!\n";
+  aResult += "!Set (override) file origin coordinate system to perform conversion during read.\n";
+  aResult += "!Default value: Yup (1). { Zup (0) | Yup (1) }\n";
+  aResult += aScope + "read.file.coordinate.system :\t " + InternalParameters.ReadFileCoordinateSys + "\n";
+  aResult += "!\n";
+
+  aResult += "!\n";
+  aResult += "!Set system origin coordinate system to perform conversion into during read.\n";
+  aResult += "!Default value: Zup (0). Available values: { Zup (0) | Yup (1) }\n";
+  aResult += aScope + "read.system.coordinate.system :\t " + InternalParameters.ReadSystemCoordinateSys + "\n";
+  aResult += "!\n";
+
+  aResult += "!\n";
+  aResult += "!Set flag allowing partially read file content to be put into the XDE document.\n";
+  aResult += "!Default value: 1(\"ON\"). Available values: 0(\"OFF\"), 1(\"ON\")\n";
+  aResult += aScope + "read.fill.incomplete :\t " + InternalParameters.ReadFillIncomplete + "\n";
+  aResult += "!\n";
+
   aResult += "!\n";
   aResult += "!Write parameters:\n";
   aResult += "!\n";
 
   aResult += "!\n";
-  aResult += "!Setting up writer version\n";
+  aResult += "!Setting up writer version.\n";
   aResult += "!Default value: 2. Available values: 1, 2\n";
   aResult += aScope + "writer.version :\t " + InternalParameters.WriterVersion + "\n";
   aResult += "!\n";
 
   aResult += "!\n";
   aResult += "!Setting up representation\n";
-  aResult += "!Default value: 1. Available values: 0(shaded), 1(wireframe), 2(both)\n";
+  aResult += "!Default value: 1. Available values: 0(shaded), 1(wireframe), 2(both).\n";
   aResult += aScope + "write.representation.type :\t " + InternalParameters.WriteRepresentationType + "\n";
   aResult += "!\n";
 
index a2402752b9f0f07e6052bf7b50028db9bcb3417e..df8b28403a2e268b6ff1db717b628fc76804907f 100644 (file)
@@ -15,6 +15,7 @@
 #define _Vrml_ConfigurationNode_HeaderFile
 
 #include <DE_ConfigurationNode.hxx>
+#include <RWMesh_CoordinateSystem.hxx>
 
 //! The purpose of this class is to configure the transfer process for VRML format
 //! Stores the necessary settings for Vrml_Provider.
@@ -93,6 +94,12 @@ public:
 
   struct Vrml_InternalSection
   {
+    // Read
+    double ReadFileUnit = 1.; //<! file length units to convert from while reading the file, defined as scale factor for meters
+    RWMesh_CoordinateSystem ReadFileCoordinateSys = RWMesh_CoordinateSystem_Yup; //<! coordinate system defined by Vrml file
+    RWMesh_CoordinateSystem ReadSystemCoordinateSys = RWMesh_CoordinateSystem_Zup; //<! result coordinate system 
+    bool ReadFillIncomplete = true; //<! fill the document with partially retrieved data even if reader has failed with error
+
     // Write
     WriteMode_WriterVersion WriterVersion = WriteMode_WriterVersion_2; //!< Setting up writer version (1/2)
     WriteMode_RepresentationType WriteRepresentationType = WriteMode_RepresentationType_Wireframe; //!< Setting up representation (shaded/wireframe/both) 
index a3db53c87ee20c2a31ea1141ba7940dee6fc41e4..005af99a69310d026753651b4d95a753c4c50dfa 100644 (file)
@@ -17,6 +17,7 @@
 #include <Message.hxx>
 #include <OSD_Path.hxx>
 #include <TDocStd_Document.hxx>
+#include <VrmlAPI_CafReader.hxx>
 #include <VrmlAPI_Writer.hxx>
 #include <VrmlData_Scene.hxx>
 #include <Vrml_ConfigurationNode.hxx>
@@ -87,14 +88,27 @@ bool Vrml_Provider::Read(const TCollection_AsciiString& thePath,
     return false;
   }
   Handle(Vrml_ConfigurationNode) aNode = Handle(Vrml_ConfigurationNode)::DownCast(GetNode());
-  TopoDS_Shape aShape;
-  if(!Read(thePath, aShape, theProgress))
+
+  VrmlAPI_CafReader aVrmlReader;
+  aVrmlReader.SetDocument(theDocument);
+  aVrmlReader.SetFileLengthUnit(aNode->InternalParameters.ReadFileUnit);
+  aVrmlReader.SetSystemLengthUnit(aNode->GlobalParameters.LengthUnit);
+  aVrmlReader.SetFileCoordinateSystem(aNode->InternalParameters.ReadFileCoordinateSys);
+  aVrmlReader.SetSystemCoordinateSystem(aNode->InternalParameters.ReadSystemCoordinateSys);
+  aVrmlReader.SetFillIncompleteDocument(aNode->InternalParameters.ReadFillIncomplete);
+
+  XCAFDoc_DocumentTool::SetLengthUnit(theDocument, aNode->InternalParameters.ReadFileUnit);
+
+  if (!aVrmlReader.Perform(thePath, theProgress))
   {
-    return false;
+    if (aVrmlReader.ExtraStatus() != RWMesh_CafReaderStatusEx_Partial)
+    {
+      Message::SendFail() << "Error in the Vrml_Provider during reading the file '" << thePath << "'";
+      return false;
+    }
+    Message::SendWarning() << "Warning in the Vrml_Provider during reading the file: file has been read paratially " <<
+      "(due to unexpected EOF, syntax error, memory limit) '" << thePath << "'";
   }
-  Handle(XCAFDoc_ShapeTool) aShTool = XCAFDoc_DocumentTool::ShapeTool(theDocument->Main());
-  aShTool->AddShape(aShape);
-  XCAFDoc_DocumentTool::SetLengthUnit(theDocument, aNode->GlobalParameters.LengthUnit, UnitsMethods_LengthUnit_Millimeter);
   return true;
 }
 
@@ -117,7 +131,7 @@ bool Vrml_Provider::Write(const TCollection_AsciiString& thePath,
 
   VrmlAPI_Writer aWriter;
   aWriter.SetRepresentation(static_cast<VrmlAPI_RepresentationOfShape>(aNode->InternalParameters.WriteRepresentationType));
-  Standard_Real aScaleFactorM = aNode->GlobalParameters.LengthUnit / 1000;
+  Standard_Real aScaleFactorM = aNode->GlobalParameters.LengthUnit;
   if (!aWriter.WriteDoc(theDocument, thePath.ToCString(), aScaleFactorM))
   {
     Message::SendFail() << "Error in the Vrml_Provider during wtiting the file " <<
@@ -199,8 +213,7 @@ bool Vrml_Provider::Read(const TCollection_AsciiString& thePath,
     }
 
     VrmlData_Scene aScene;
-    Standard_Real anOCCUnitMM = aNode->GlobalParameters.LengthUnit;
-    aScene.SetLinearScale(1000. / anOCCUnitMM);
+    aScene.SetLinearScale(aNode->GlobalParameters.LengthUnit);
 
     aScene.SetVrmlDir(aVrmlDir);
     aScene << aStream;
index 7f3fb4a3fad1d4ee065bcdd71ec88965de4f51a7..97f69df8a94931e5e482f1fdb80d4a354d724200 100644 (file)
@@ -1,5 +1,7 @@
 VrmlAPI.cxx
 VrmlAPI.hxx
+VrmlAPI_CafReader.cxx
+VrmlAPI_CafReader.hxx
 VrmlAPI_RepresentationOfShape.hxx
 VrmlAPI_Writer.cxx
 VrmlAPI_Writer.hxx
diff --git a/src/VrmlAPI/VrmlAPI_CafReader.cxx b/src/VrmlAPI/VrmlAPI_CafReader.cxx
new file mode 100644 (file)
index 0000000..523442d
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright (c) 2022 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 <VrmlAPI_CafReader.hxx>
+
+#include <OSD_FileSystem.hxx>
+#include <OSD_OpenFile.hxx>
+#include <OSD_Path.hxx>
+#include <Message.hxx>
+#include <Standard_CLocaleSentry.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <VrmlData_Scene.hxx>
+
+#include <memory>
+
+IMPLEMENT_STANDARD_RTTIEXT(VrmlAPI_CafReader, Standard_Transient)
+
+namespace
+{
+  //=======================================================================
+  // function : getVrmlErrorName
+  // purpose  :
+  //=======================================================================
+  static TCollection_AsciiString getVrmlErrorName(VrmlData_ErrorStatus theStatus)
+  {
+    switch (theStatus)
+    {
+      case VrmlData_StatusOK:              return "";
+      case VrmlData_EmptyData:             return "EmptyData";
+      case VrmlData_UnrecoverableError:    return "UnrecoverableError";
+      case VrmlData_GeneralError:          return "GeneralError";
+      case VrmlData_EndOfFile:             return "EndOfFile";
+      case VrmlData_NotVrmlFile:           return "NotVrmlFile";
+      case VrmlData_CannotOpenFile:        return "CannotOpenFile";
+      case VrmlData_VrmlFormatError:       return "VrmlFormatError";
+      case VrmlData_NumericInputError:     return "NumericInputError";
+      case VrmlData_IrrelevantNumber:      return "IrrelevantNumber";
+      case VrmlData_BooleanInputError:     return "BooleanInputError";
+      case VrmlData_StringInputError:      return "StringInputError";
+      case VrmlData_NodeNameUnknown:       return "NodeNameUnknown";
+      case VrmlData_NonPositiveSize:       return "NonPositiveSize";
+      case VrmlData_ReadUnknownNode:       return "ReadUnknownNode";
+      case VrmlData_NonSupportedFeature:   return "NonSupportedFeature";
+      case VrmlData_OutputStreamUndefined: return "OutputStreamUndefined";
+      case VrmlData_NotImplemented:        return "NotImplemented";
+    }
+    return "UNKNOWN";
+  }
+
+  //=======================================================================
+  // function : performMeshSubshape
+  // purpose  :
+  //=======================================================================
+  static void performMeshSubshape(RWMesh_NodeAttributeMap& theAttribMap,
+                                  const VrmlData_DataMapOfShapeAppearance& theShapeAppMap,
+                                  const TopoDS_Shape& theShape)
+  {
+    Handle(VrmlData_Appearance) anAppearance;
+    if (theShapeAppMap.Find(theShape.TShape(), anAppearance))
+    {
+      if (!anAppearance.IsNull()
+          && !anAppearance->Material().IsNull())
+      {
+        RWMesh_NodeAttributes aFaceAttribs;
+        theAttribMap.Find(theShape, aFaceAttribs);
+        aFaceAttribs.Style.SetColorSurf(anAppearance->Material()->DiffuseColor());
+        theAttribMap.Bind(theShape, aFaceAttribs);
+      }
+    }
+
+    for (TopoDS_Iterator aSubShapeIter(theShape, true, false); aSubShapeIter.More(); aSubShapeIter.Next())
+    {
+      performMeshSubshape(theAttribMap, theShapeAppMap, aSubShapeIter.Value());
+    }
+  }
+}
+
+//=======================================================================
+// function : performMesh
+// purpose  :
+//=======================================================================
+bool VrmlAPI_CafReader::performMesh(const TCollection_AsciiString& theFile,
+                                    const Message_ProgressRange& theProgress,
+                                    const Standard_Boolean theToProbe)
+{
+  (void)theProgress;
+  Handle(OSD_FileSystem) aFile = OSD_FileSystem::DefaultFileSystem();
+  std::shared_ptr<std::istream> aFileStream = aFile->OpenIStream(theFile, std::ios::in | std::ios::binary);
+  if (aFileStream.get() == nullptr || !aFileStream->good())
+  {
+    Message::SendFail() << "Error in VrmlAPI_CafReader: file '" << theFile << "' is not found";
+    return false;
+  }
+  if (theToProbe)
+  {
+    Message::SendFail() << "Error in VrmlAPI_CafReader: theToProbe parameter isn't supported";
+    return false; // unsupported
+  }
+
+  // determine file location to load associated files
+  TCollection_AsciiString aFolder;
+  TCollection_AsciiString aFileName;
+  OSD_Path::FolderAndFileFromPath(theFile, aFolder, aFileName);
+
+  VrmlData_Scene aScene;
+  aScene.SetLinearScale(FileLengthUnit());
+  aScene.SetVrmlDir(aFolder);
+  aScene << *aFileStream;
+
+  VrmlData_DataMapOfShapeAppearance aShapeAppMap;
+  TopoDS_Shape aShape = aScene.GetShape(aShapeAppMap);
+  if (!aShape.IsNull())
+  {
+    performMeshSubshape(myAttribMap, aShapeAppMap, aShape);
+    myRootShapes.Append(aShape);
+  }
+  if (aScene.Status() != VrmlData_StatusOK
+      || aShape.IsNull())
+  {
+    Message::SendFail() << "Error in VrmlAPI_CafReader: " << getVrmlErrorName(aScene.Status())
+                        << "occurred at line " << aScene.GetLineError()
+                        << "\nwhile reading VRML file '" << theFile << "'";
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/VrmlAPI/VrmlAPI_CafReader.hxx b/src/VrmlAPI/VrmlAPI_CafReader.hxx
new file mode 100644 (file)
index 0000000..87af90d
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2022 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.
+
+#ifndef _VrmlAPI_Reader_HeaderFile
+#define _VrmlAPI_Reader_HeaderFile
+
+#include <RWMesh_CafReader.hxx>
+
+//! The Vrml mesh reader into XDE document.
+class VrmlAPI_CafReader : public RWMesh_CafReader
+{
+  DEFINE_STANDARD_RTTIEXT(VrmlAPI_CafReader, RWMesh_CafReader)
+
+protected:
+
+  //! Read the mesh data from specified file.
+  //! @param theFile     file to read
+  //! @param theProgress progress indicator
+  //! @param theToProbe  flag for probing file without complete reading. Not supported.
+  //! @return false when theToProbe is set to true or reading has completed with error.
+  Standard_EXPORT virtual Standard_Boolean performMesh(const TCollection_AsciiString& theFile,
+                                                       const Message_ProgressRange&   theProgress,
+                                                       const Standard_Boolean         theToProbe) Standard_OVERRIDE;
+
+};
+
+#endif // _VrmlAPI_Reader_HeaderFile
index e047a2522a5a1538d90c1a584e465ac3e704caaa..3da83663125f009db21b63164c1b2a0718268851 100644 (file)
@@ -13,7 +13,6 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <DDocStd.hxx>
 #include <DDocStd_DrawDocument.hxx>
 #include <DE_ConfigurationContext.hxx>
@@ -39,6 +38,7 @@
 #include <XSControl_WorkSession.hxx>
 #include <XSDRAW.hxx>
 #include <XSDRAW_Vars.hxx>
+#include <VrmlAPI_CafReader.hxx>
 #include <VrmlAPI_Writer.hxx>
 #include <DDF.hxx>
 
@@ -49,6 +49,7 @@
 #include <TDF_Tool.hxx>
 #include <TopoDS_Shape.hxx>
 #include <Interface_Static.hxx>
+#include <UnitsAPI.hxx>
 #include <UnitsMethods.hxx>
 
 #include <stdio.h>
 //============================================================
 static NCollection_DataMap<TCollection_AsciiString, Handle(Standard_Transient)> thedictws;
 
+//=======================================================================
+//function : parseCoordinateSystem
+//purpose  : Parse RWMesh_CoordinateSystem enumeration.
+//=======================================================================
+static bool 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;
+}
+
 static Standard_Boolean ClearDicWS()
 {
   thedictws.Clear();
@@ -721,6 +746,142 @@ static Standard_Integer Extract(Draw_Interpretor& di,
   return 0;
 }
 
+//=======================================================================
+//function : ReadVrml
+//purpose  :
+//=======================================================================
+static Standard_Integer ReadVrml(Draw_Interpretor& theDI,
+                                 Standard_Integer  theArgc,
+                                 const char**      theArgv)
+{
+  if(theArgc < 3)
+  {
+    theDI.PrintHelp(theArgv[0]);
+    return 1;
+  }
+
+  Handle(TDocStd_Document) aDoc;
+  Standard_Real aFileUnitFactor = 1.0;
+  RWMesh_CoordinateSystem aFileCoordSys = RWMesh_CoordinateSystem_Yup, aSystemCoordSys = RWMesh_CoordinateSystem_Zup;
+  Standard_Boolean toUseExistingDoc = Standard_False;
+  Standard_Boolean toFillIncomplete = Standard_True;
+  Standard_CString aDocName = NULL;
+  TCollection_AsciiString aFilePath;
+
+  for(Standard_Integer anArgIt = 1; anArgIt < theArgc; anArgIt++)
+  {
+    TCollection_AsciiString anArg(theArgv[anArgIt]);
+    anArg.LowerCase();
+    if(anArgIt + 1 < theArgc && anArg == "-fileunit")
+    {
+      const TCollection_AsciiString aUnitStr(theArgv[++anArgIt]);
+      aFileUnitFactor = UnitsAPI::AnyToSI(1.0, aUnitStr.ToCString());
+      if (aFileUnitFactor <= 0.0)
+      {
+        Message::SendFail() << "Error: wrong length unit '" << aUnitStr << "'";
+        return 1;
+      }
+    }
+    else if (anArgIt + 1 < theArgc && anArg == "-filecoordsys")
+    {
+      if (!parseCoordinateSystem(theArgv[++anArgIt], aFileCoordSys))
+      {
+        Message::SendFail() << "Error: unknown coordinate system '" << theArgv[anArgIt] << "'";
+        return 1;
+      }
+    }
+    else if (anArgIt + 1 < theArgc && anArg == "-systemcoordsys")
+    {
+      if (!parseCoordinateSystem(theArgv[++anArgIt], aSystemCoordSys))
+      {
+        Message::SendFail() << "Error: unknown coordinate system '" << theArgv[anArgIt] << "'";
+        return 1;
+      }
+    }
+    else if (anArg == "-fillincomplete")
+    {
+      toFillIncomplete = true;
+      if (anArgIt + 1 < theArgc && Draw::ParseOnOff(theArgv[anArgIt + 1], toFillIncomplete))
+      {
+        ++anArgIt;
+      }
+    }
+    else if (anArg == "-nocreatedoc")
+    {
+      toUseExistingDoc = true;
+    }
+    else if (aDocName == nullptr)
+    {
+      aDocName = theArgv[anArgIt];
+      DDocStd::GetDocument(aDocName, aDoc, Standard_False);
+    }
+    else if(aFilePath.IsEmpty())
+    {
+      aFilePath = theArgv[anArgIt];
+    }
+    else
+    {
+      Message::SendFail() << "Syntax error at '" << theArgv[anArgIt] << "'";
+      return 1;
+    }
+  }
+
+  if (aFilePath.IsEmpty() || aDocName == nullptr)
+  {
+    Message::SendFail() << "Syntax error: wrong number of arguments";
+    return 1;
+  }
+  
+  if (aDoc.IsNull())
+  {
+    if(toUseExistingDoc)
+    {
+      Message::SendFail() << "Error: document with name " << aDocName << " does not exist";
+      return 1;
+    }
+    Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
+    anApp->NewDocument("BinXCAF", aDoc);
+  }
+  else if (!toUseExistingDoc)
+  {
+    Message::SendFail() << "Error: document with name " << aDocName << " already exists\n";
+    return 1;
+  }
+
+  Standard_Real aScaleFactor = 1.;
+  if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactor))
+  {
+    XSAlgo::AlgoContainer()->PrepareForTransfer();
+    aScaleFactor = UnitsMethods::GetCasCadeLengthUnit();
+  }
+
+  VrmlAPI_CafReader aVrmlReader;
+  aVrmlReader.SetDocument(aDoc);
+  aVrmlReader.SetFileLengthUnit(aFileUnitFactor);
+  aVrmlReader.SetSystemLengthUnit(aScaleFactor);
+  aVrmlReader.SetFileCoordinateSystem(aFileCoordSys);
+  aVrmlReader.SetSystemCoordinateSystem(aSystemCoordSys);
+  aVrmlReader.SetFillIncompleteDocument(toFillIncomplete);
+
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(theDI, 1);
+  if (!aVrmlReader.Perform(aFilePath, aProgress->Start()))
+  {
+    if (aVrmlReader.ExtraStatus() != RWMesh_CafReaderStatusEx_Partial)
+    {
+      Message::SendFail() << "Error: file reading failed '" << aFilePath << "'";
+      return 1;
+    }
+    Message::SendWarning() <<
+      "Warning: file has been read paratially (due to unexpected EOF, syntax error, memory limit) " << aFilePath;
+  }
+
+  TDataStd_Name::Set(aDoc->GetData()->Root(), aDocName);
+  Handle(DDocStd_DrawDocument) aDD = new DDocStd_DrawDocument(aDoc);
+  Draw::Set(aDocName, aDD);
+
+  return 0;
+}
+
 //=======================================================================
 //function : WriteVrml
 //purpose  : Write DECAF document to Vrml
@@ -1126,7 +1287,20 @@ void XDEDRAW_Common::InitCommands(Draw_Interpretor& di)
          "Extracts given srcLabel1 srcLabel2 ... from srcDoc into given Doc or assembly shape",
          __FILE__, Extract, g);
 
-  di.Add("WriteVrml", "Doc filename [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 0 by default]", __FILE__, WriteVrml, g);
+  di.Add("ReadVrml",
+         "ReadVrml docName filePath [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
+         "\n\t\t:                   [-systemCoordSys {Zup|Yup}] [-noCreateDoc] [-fillIncomplete {ON|OFF}]"
+         "\n\t\t: Read Vrml file into XDE document."
+         "\n\t\t:   -fileCoordSys   coordinate system defined by Vrml file; Yup when not specified."
+         "\n\t\t:   -fileUnit       length unit of Vrml file content."
+         "\n\t\t:   -systemCoordSys result coordinate system; Zup when not specified."
+         "\n\t\t:   -noCreateDoc    read into existing XDE document."
+         "\n\t\t:   -fillIncomplete fill the document with partially retrieved data even if reader has failed with "
+         "error; true when not specified", 
+         __FILE__, ReadVrml, g);
+  di.Add("WriteVrml",
+         "WriteVrml Doc filename [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 0 by default]",
+         __FILE__, WriteVrml, g);
 
   di.Add("DumpConfiguration",
          "DumpConfiguration [-path <path>] [-recursive {on|off}] [-format fmt1 fmt2 ...] [-vendor vend1 vend2 ...]\n"
index 8c433645f0f3f4295667814e152a39fcc782181d..52d90197328e93f59209ba7490e2e906670b1417 100644 (file)
@@ -7,4 +7,5 @@
 007 obj_write
 008 ply_write
 009 step_read
-010 step_write
\ No newline at end of file
+010 step_write
+011 vrml_read
\ No newline at end of file
diff --git a/tests/de_mesh/vrml_read/A1 b/tests/de_mesh/vrml_read/A1
new file mode 100644 (file)
index 0000000..6d2c371
--- /dev/null
@@ -0,0 +1,32 @@
+puts "============"
+puts "0032820: Data Exchange - add VRML reader to XCAF document"
+puts "============"
+puts ""
+
+set aFile [locate_data_file bug29597_vrml2.wrl]
+
+catch { Close D }
+
+loadvrml S_${casename} $aFile
+vinit Driver1/View_${casename}_1/${casename}_1
+vdisplay S_${casename} -dispmode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_1.png
+
+XNewDoc D
+ReadVrml D $aFile -nocreatedoc
+vinit Driver1/View_${casename}_2/${casename}_2
+XDisplay D -dispMode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_2.png
+
+XGetOneShape S_New D
+checktrinfo S_New -ref [trinfo S_${casename}]
+
+set ref_colors "TEAL "
+set new_colors [ XGetAllColors D ]
+if {[ string equal $new_colors $ref_colors ] == 0} {
+  puts "Error: Colors have been read incorrectly."
+}  
+
+Close D
diff --git a/tests/de_mesh/vrml_read/A2 b/tests/de_mesh/vrml_read/A2
new file mode 100644 (file)
index 0000000..868102f
--- /dev/null
@@ -0,0 +1,25 @@
+puts "============"
+puts "0032820: Data Exchange - add VRML reader to XCAF document"
+puts "============"
+puts ""
+
+set aFile [locate_data_file M_2056112640_E.wrl]
+
+catch { Close D }
+
+loadvrml S_${casename} $aFile
+vinit Driver1/View_${casename}_1/${casename}_1
+vdisplay S_${casename} -dispmode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_1.png
+
+XNewDoc D
+ReadVrml D $aFile -nocreatedoc
+vinit Driver1/View_${casename}_2/${casename}_2
+XDisplay D -dispMode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_2.png
+
+XGetOneShape S_New D
+checktrinfo S_New -ref [trinfo S_${casename}]
+Close D
diff --git a/tests/de_mesh/vrml_read/A3 b/tests/de_mesh/vrml_read/A3
new file mode 100644 (file)
index 0000000..42b7285
--- /dev/null
@@ -0,0 +1,32 @@
+puts "============"
+puts "0032820: Data Exchange - add VRML reader to XCAF document"
+puts "============"
+puts ""
+
+set aFile [locate_data_file OCC22092-sk97.wrl]
+
+catch { Close D }
+
+loadvrml S_${casename} $aFile
+vinit Driver1/View_${casename}_1/${casename}_1
+vdisplay S_${casename} -dispmode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_1.png
+
+XNewDoc D
+ReadVrml D $aFile -nocreatedoc
+vinit Driver1/View_${casename}_2/${casename}_2
+XDisplay D -dispMode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_2.png
+
+XGetOneShape S_New D
+checktrinfo S_New -tol_abs_defl 1e-14 -ref [trinfo S_${casename}]
+
+set ref_colors "BLACK "
+set new_colors [ XGetAllColors D ]
+if {[ string equal $new_colors $ref_colors ] == 0} {
+  puts "Error: Colors have been read incorrectly."
+}
+
+Close D
diff --git a/tests/de_mesh/vrml_read/A4 b/tests/de_mesh/vrml_read/A4
new file mode 100644 (file)
index 0000000..a9e0ca4
--- /dev/null
@@ -0,0 +1,22 @@
+puts "============"
+puts "0032820: Data Exchange - add VRML reader to XCAF document"
+puts "============"
+puts ""
+
+set aFile [locate_data_file OCC23023-2056132060_2_tutnicht.wrl]
+
+catch { Close D }
+
+XNewDoc D
+ReadVrml D $aFile -nocreatedoc
+vinit Driver1/View_${casename}_1/${casename}_1
+XDisplay D -dispMode 1
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}_1.png
+
+set ref_colors "GRAY76 GRAY64 WHITE TURQUOISE4 "
+set d_colors [ XGetAllColors D ]
+
+if { [ string equal $d_colors $ref_colors ] == 0 } {
+  puts "Error: Colors have been read incorrectly." 
+}
diff --git a/tests/de_mesh/vrml_read/begin b/tests/de_mesh/vrml_read/begin
new file mode 100644 (file)
index 0000000..23c0924
--- /dev/null
@@ -0,0 +1,5 @@
+# File: begin
+
+pload XDE
+pload OCAF
+pload TOPTEST
index 2e0d1456fcfdda5f0dd3e12ad0abab36e1f36024..a54692fb9c8d64931fa6eaf49951918688cddc40 100644 (file)
@@ -61,6 +61,11 @@ provider.STEP.OCC.write.name :   1
 provider.STEP.OCC.write.layer :  1
 provider.STEP.OCC.write.props :  1
 provider.STEP.OCC.write.model.type :     0
+provider.VRML.OCC.read.file.unit :       1
+provider.VRML.OCC.read.memory.limit :    -1
+provider.VRML.OCC.read.file.coordinate.system :  1
+provider.VRML.OCC.read.system.coordinate.system :        0
+provider.VRML.OCC.read.fill.incomplete :         1
 provider.VRML.OCC.writer.version :       2
 provider.VRML.OCC.write.representation.type :    1
 provider.STL.OCC.read.merge.angle :      90
index f71d00449fc378bb7de1562db41d23c4eace1879..1a61df6fe47f0430ade44c4dc12e1d8779bd32cb 100644 (file)
@@ -19,25 +19,25 @@ if [catch {loadvrml res1 $filename} catch_result] {
     puts "OK : Reading is correct"
 }
 
-if [catch {ReadFile D2 $filename} catch_result] {
+if [catch {ReadFile D2 $filename -conf "provider.VRML.OCC.read.file.unit : 1000"} catch_result] {
     puts "Error : Problem with reading file"
 } else {
     puts "OK : Reading is correct"
 }
 XGetOneShape S2 D2
-if { [XGetLengthUnit D2] != "mm" } {
+if { [XGetLengthUnit D2] != "km" } {
   puts "Error: incrorrect document's length unit"
 }
 
 XNewDoc D3
-if [catch {ReadFile D3 $filename -conf "global.general.length.unit : 1000 " } catch_result] {
+if [catch {ReadFile D3 $filename -conf "provider.VRML.OCC.read.file.unit : 0.001" } catch_result] {
     puts "Error : Problem with reading file"
 } else {
     puts "OK : Reading is correct"
 }
 XGetOneShape S3 D3
 
-if [catch {readfile S4 $filename } catch_result] {
+if [catch {readfile S4 $filename -conf "global.general.length.unit : 0.001 "} catch_result] {
     puts "Error : Problem with reading file"
 } else {
     puts "OK : Reading is correct"
@@ -49,7 +49,7 @@ if [catch {readfile S5 $filename -conf "global.general.length.unit : 1000 " } ca
     puts "OK : Reading is correct"
 }
 
-array set areas {0 5.3415e+06 1 5.3415 2 5.3415e+06 3 5.3415 4 5.3415e+06 5 5.3415}
+array set areas {0 5.3415e+06 1 5.3415 2 5.3415e+06 3 5.3415e-06 4 5.3415e-06 5 5.3415e+06}
 array set results {0 res0 1 res1 2 S2 3 S3 4 S4 5 S5}
 for { set anind 0} { $anind < 6 } { incr anind } {
   checkprops $results($anind) -s $areas($anind) -eps 1e-2
index c823bf13265b057d83a30113df36c86782386f7a..449b313526703aac02c247992c8fad433e006df1 100644 (file)
@@ -79,7 +79,7 @@ if [catch {WriteFile D0 $write_path} catch_result] {
 } else {
     puts "OK : Writing is correct"
 }
-if [catch {ReadFile D6 $write_path -conf "global.general.length.unit : 1 "} catch_result] {
+if [catch {ReadFile D6 $write_path -conf "provider.VRML.OCC.read.file.unit : 1"} catch_result] {
     puts "Error : Problem with reading file"
 } else {
     puts "OK : Reading is correct"
@@ -91,7 +91,7 @@ if [catch {writefile S1 $write_path} catch_result] {
 } else {
     puts "OK : Writing is correct"
 }
-if [catch {ReadFile D7 $write_path -conf "global.general.length.unit : 1000 "} catch_result] {
+if [catch {ReadFile D7 $write_path -conf "provider.VRML.OCC.read.file.unit : 0.001"} catch_result] {
     puts "Error : Problem with reading file"
 } else {
     puts "OK : Reading is correct"