#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 <RWGltf_CafWriter.hxx>
#include <RWStl.hxx>
+#include <RWObj.hxx>
+#include <RWObj_CafReader.hxx>
#include <SelectMgr_SelectionManager.hxx>
#include <Standard_ErrorHandler.hxx>
#include <StdSelect_ViewerSelector3d.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 <VrmlData_DataMapOfShapeAppearance.hxx>
#include <VrmlData_Scene.hxx>
#include <VrmlData_ShapeConvert.hxx>
+#include <XCAFDoc_DocumentTool.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
#include <XSDRAW.hxx>
#include <XSDRAWIGES.hxx>
#include <XSDRAWSTEP.hxx>
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;
+}
+
+//=============================================================================
+//function : WriteGltf
+//purpose : Writes glTF file
+//=============================================================================
+static Standard_Integer WriteGltf (Draw_Interpretor& theDI,
+ Standard_Integer theNbArgs,
+ const char** theArgVec)
+{
+ TCollection_AsciiString aGltfFilePath;
+ Handle(TDocStd_Document) aDoc;
+ Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
+ TColStd_IndexedDataMapOfStringString aFileInfo;
+ RWGltf_WriterTrsfFormat aTrsfFormat = RWGltf_WriterTrsfFormat_Compact;
+ bool toForceUVExport = false;
+ for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+ {
+ TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
+ anArgCase.LowerCase();
+ if (anArgCase == "-comments"
+ && anArgIter + 1 < theNbArgs)
+ {
+ aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
+ }
+ else if (anArgCase == "-author"
+ && anArgIter + 1 < theNbArgs)
+ {
+ aFileInfo.Add ("Author", theArgVec[++anArgIter]);
+ }
+ else if (anArgCase == "-forceuvexport"
+ || anArgCase == "-forceuv")
+ {
+ toForceUVExport = true;
+ if (anArgIter + 1 < theNbArgs
+ && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toForceUVExport))
+ {
+ ++anArgIter;
+ }
+ }
+ else if (anArgCase == "-trsfformat"
+ && anArgIter + 1 < theNbArgs)
+ {
+ TCollection_AsciiString aTrsfStr (theArgVec[++anArgIter]);
+ aTrsfStr.LowerCase();
+ if (aTrsfStr == "compact")
+ {
+ aTrsfFormat = RWGltf_WriterTrsfFormat_Compact;
+ }
+ else if (aTrsfStr == "mat4")
+ {
+ aTrsfFormat = RWGltf_WriterTrsfFormat_Mat4;
+ }
+ else if (aTrsfStr == "trs")
+ {
+ aTrsfFormat = RWGltf_WriterTrsfFormat_TRS;
+ }
+ else
+ {
+ std::cout << "Syntax error at '" << anArgCase << "'\n";
+ return 1;
+ }
+ }
+ else if (aDoc.IsNull())
+ {
+ Standard_CString aNameVar = theArgVec[anArgIter];
+ DDocStd::GetDocument (aNameVar, aDoc, false);
+ if (aDoc.IsNull())
+ {
+ TopoDS_Shape aShape = DBRep::Get (aNameVar);
+ if (aShape.IsNull())
+ {
+ std::cout << "Syntax error: '" << aNameVar << "' is not a shape nor document\n";
+ return 1;
+ }
+
+ anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
+ Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
+ aShapeTool->AddShape (aShape);
+ }
+ }
+ else if (aGltfFilePath.IsEmpty())
+ {
+ aGltfFilePath = theArgVec[anArgIter];
+ }
+ else
+ {
+ std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
+ return 1;
+ }
+ }
+ if (aGltfFilePath.IsEmpty())
+ {
+ std::cout << "Syntax error: wrong number of arguments\n";
+ return 1;
+ }
+
+ Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
+
+ TCollection_AsciiString anExt = aGltfFilePath;
+ anExt.LowerCase();
+
+ const Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
+
+ RWGltf_CafWriter aWriter (aGltfFilePath, anExt.EndsWith (".glb"));
+ aWriter.SetTransformationFormat (aTrsfFormat);
+ aWriter.SetForcedUVExport (toForceUVExport);
+ aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aSystemUnitFactor);
+ aWriter.ChangeCoordinateSystemConverter().SetInputCoordinateSystem (RWMesh_CoordinateSystem_Zup);
+ aWriter.Perform (aDoc, aFileInfo, aProgress);
+ return 0;
+}
+
static Standard_Integer writestl
(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
}
StlAPI_Writer aWriter;
aWriter.ASCIIMode() = isASCIIMode;
- Standard_Boolean isOK = aWriter.Write (aShape, argv[2]);
+ Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
+ Standard_Boolean isOK = aWriter.Write (aShape, argv[2], aProgress);
if (!isOK)
di << "** Error **: Mesh writing has been failed.\n";
}
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;
+}
+
static Standard_Integer writevrml
(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
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;
}
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]);
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 ("WriteGltf",
+ "WriteGltf Doc file [-trsfFormat {compact|TRS|mat4}=compact] [-comments Text] [-author Name] [-forceUVExport]"
+ "\n\t\t: Write XDE document into glTF file."
+ "\n\t\t: -trsfFormat preferred transformation format"
+ "\n\t\t: -forceUVExport always export UV coordinates",
+ __FILE__, WriteGltf, g);
+ theCommands.Add ("writegltf",
+ "writegltf shape file",
+ __FILE__, WriteGltf, 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",
"\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 );