Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:42

0001 // Copyright (c) 2017-2019 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _RWGltf_CafWriter_HeaderFiler
0015 #define _RWGltf_CafWriter_HeaderFiler
0016 
0017 #include <TColStd_IndexedDataMapOfStringString.hxx>
0018 #include <TColStd_MapOfAsciiString.hxx>
0019 #include <TDF_LabelSequence.hxx>
0020 #include <TopTools_ShapeMapHasher.hxx>
0021 #include <RWGltf_DracoParameters.hxx>
0022 #include <RWGltf_GltfBufferView.hxx>
0023 #include <RWGltf_GltfFace.hxx>
0024 #include <RWGltf_WriterTrsfFormat.hxx>
0025 #include <RWMesh_CoordinateSystemConverter.hxx>
0026 #include <RWMesh_NameFormat.hxx>
0027 #include <XCAFPrs_Style.hxx>
0028 #include <Poly_Triangle.hxx>
0029 
0030 #include <memory>
0031 
0032 class Message_ProgressRange;
0033 class RWMesh_FaceIterator;
0034 class RWGltf_GltfOStreamWriter;
0035 class RWGltf_GltfMaterialMap;
0036 class RWGltf_GltfSceneNodeMap;
0037 class TDocStd_Document;
0038 
0039 //! glTF writer context from XCAF document.
0040 class RWGltf_CafWriter : public Standard_Transient
0041 {
0042   DEFINE_STANDARD_RTTIEXT(RWGltf_CafWriter, Standard_Transient)
0043 public:
0044 
0045   //! Mesh
0046   struct Mesh
0047   {
0048     std::vector<Graphic3d_Vec3> NodesVec;     //!< vector for mesh nodes
0049     std::vector<Graphic3d_Vec3> NormalsVec;   //!< vector for mesh normals
0050     std::vector<Graphic3d_Vec2> TexCoordsVec; //!< vector for mesh texture UV coordinates
0051     std::vector<Poly_Triangle>  IndicesVec;   //!< vector for mesh indices
0052   };
0053 
0054   //! Main constructor.
0055   //! @param theFile     [in] path to output glTF file
0056   //! @param theIsBinary [in] flag to write into binary glTF format (.glb)
0057   Standard_EXPORT RWGltf_CafWriter (const TCollection_AsciiString& theFile,
0058                                     Standard_Boolean theIsBinary);
0059 
0060   //! Destructor.
0061   Standard_EXPORT virtual ~RWGltf_CafWriter();
0062 
0063   //! Return transformation from OCCT to glTF coordinate system.
0064   const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCSTrsf; }
0065 
0066   //! Return transformation from OCCT to glTF coordinate system.
0067   RWMesh_CoordinateSystemConverter& ChangeCoordinateSystemConverter() { return myCSTrsf; }
0068 
0069   //! Set transformation from OCCT to glTF coordinate system.
0070   void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCSTrsf = theConverter; }
0071 
0072   //! Return flag to write into binary glTF format (.glb), specified within class constructor.
0073   bool IsBinary() const { return myIsBinary; }
0074 
0075   //! Return preferred transformation format for writing into glTF file; RWGltf_WriterTrsfFormat_Compact by default.
0076   RWGltf_WriterTrsfFormat TransformationFormat() const { return myTrsfFormat; }
0077 
0078   //! Set preferred transformation format for writing into glTF file.
0079   void SetTransformationFormat (RWGltf_WriterTrsfFormat theFormat) { myTrsfFormat = theFormat; }
0080 
0081   //! Return name format for exporting Nodes; RWMesh_NameFormat_InstanceOrProduct by default.
0082   RWMesh_NameFormat NodeNameFormat() const { return myNodeNameFormat; }
0083 
0084   //! Set name format for exporting Nodes.
0085   void SetNodeNameFormat (RWMesh_NameFormat theFormat) { myNodeNameFormat = theFormat; }
0086 
0087   //! Return name format for exporting Meshes; RWMesh_NameFormat_Product by default.
0088   RWMesh_NameFormat MeshNameFormat() const { return myMeshNameFormat; }
0089 
0090   //! Set name format for exporting Meshes.
0091   void SetMeshNameFormat (RWMesh_NameFormat theFormat) { myMeshNameFormat = theFormat; }
0092 
0093   //! Return TRUE to export UV coordinates even if there are no mapped texture; FALSE by default.
0094   bool IsForcedUVExport() const { return myIsForcedUVExport; }
0095 
0096   //! Set flag to export UV coordinates even if there are no mapped texture; FALSE by default.
0097   void SetForcedUVExport (bool theToForce) { myIsForcedUVExport = theToForce; }
0098 
0099   //! Return default material definition to be used for nodes with only color defined.
0100   const XCAFPrs_Style& DefaultStyle() const { return myDefaultStyle; }
0101 
0102   //! Set default material definition to be used for nodes with only color defined.
0103   void SetDefaultStyle (const XCAFPrs_Style& theStyle) { myDefaultStyle = theStyle; }
0104 
0105   //! Return flag to write image textures into GLB file (binary gltf export); TRUE by default.
0106   //! When set to FALSE, texture images will be written as separate files.
0107   //! Has no effect on writing into non-binary format.
0108   Standard_Boolean ToEmbedTexturesInGlb() { return myToEmbedTexturesInGlb; }
0109 
0110   //! Set flag to write image textures into GLB file (binary gltf export).
0111   void SetToEmbedTexturesInGlb (Standard_Boolean theToEmbedTexturesInGlb) { myToEmbedTexturesInGlb = theToEmbedTexturesInGlb; }
0112 
0113   //! Return flag to merge faces within a single part; FALSE by default.
0114   bool ToMergeFaces() const { return myToMergeFaces; }
0115 
0116   //! Set flag to merge faces within a single part.
0117   //! May reduce JSON size thanks to smaller number of primitive arrays.
0118   void SetMergeFaces (bool theToMerge) { myToMergeFaces = theToMerge; }
0119 
0120   //! Return flag to prefer keeping 16-bit indexes while merging face; FALSE by default.
0121   bool ToSplitIndices16() const { return myToSplitIndices16; }
0122 
0123   //! Set flag to prefer keeping 16-bit indexes while merging face.
0124   //! Has effect only with ToMergeFaces() option turned ON.
0125   //! May reduce binary data size thanks to smaller triangle indexes.
0126   void SetSplitIndices16 (bool theToSplit) { myToSplitIndices16 = theToSplit; }
0127 
0128   //! Return TRUE if multithreaded optimizations are allowed; FALSE by default.
0129   bool ToParallel() const { return myToParallel; }
0130 
0131   //! Setup multithreaded execution.
0132   void SetParallel (bool theToParallel) { myToParallel = theToParallel; }
0133 
0134   //! Return Draco parameters
0135   const RWGltf_DracoParameters& CompressionParameters() const { return myDracoParameters; }
0136 
0137   //! Set Draco parameters
0138   void SetCompressionParameters(const RWGltf_DracoParameters& theDracoParameters) { myDracoParameters = theDracoParameters; }
0139 
0140   //! Write glTF file and associated binary file.
0141   //! Triangulation data should be precomputed within shapes!
0142   //! @param theDocument    [in] input document
0143   //! @param theRootLabels  [in] list of root shapes to export
0144   //! @param theLabelFilter [in] optional filter with document nodes to export,
0145   //!                            with keys defined by XCAFPrs_DocumentExplorer::DefineChildId() and filled recursively
0146   //!                            (leaves and parent assembly nodes at all levels);
0147   //!                            when not NULL, all nodes not included into the map will be ignored
0148   //! @param theFileInfo    [in] map with file metadata to put into glTF header section
0149   //! @param theProgress    [in] optional progress indicator
0150   //! @return FALSE on file writing failure
0151   Standard_EXPORT virtual bool Perform (const Handle(TDocStd_Document)& theDocument,
0152                                         const TDF_LabelSequence& theRootLabels,
0153                                         const TColStd_MapOfAsciiString* theLabelFilter,
0154                                         const TColStd_IndexedDataMapOfStringString& theFileInfo,
0155                                         const Message_ProgressRange& theProgress);
0156 
0157   //! Write glTF file and associated binary file.
0158   //! Triangulation data should be precomputed within shapes!
0159   //! @param theDocument    [in] input document
0160   //! @param theFileInfo    [in] map with file metadata to put into glTF header section
0161   //! @param theProgress    [in] optional progress indicator
0162   //! @return FALSE on file writing failure
0163   Standard_EXPORT virtual bool Perform (const Handle(TDocStd_Document)& theDocument,
0164                                         const TColStd_IndexedDataMapOfStringString& theFileInfo,
0165                                         const Message_ProgressRange& theProgress);
0166 
0167 protected:
0168 
0169   //! Write binary data file with triangulation data.
0170   //! Triangulation data should be precomputed within shapes!
0171   //! @param theDocument    [in] input document
0172   //! @param theRootLabels  [in] list of root shapes to export
0173   //! @param theLabelFilter [in] optional filter with document nodes to export
0174   //! @param theProgress    [in] optional progress indicator
0175   //! @return FALSE on file writing failure
0176   Standard_EXPORT virtual bool writeBinData (const Handle(TDocStd_Document)& theDocument,
0177                                              const TDF_LabelSequence& theRootLabels,
0178                                              const TColStd_MapOfAsciiString* theLabelFilter,
0179                                              const Message_ProgressRange& theProgress);
0180 
0181   //! Write JSON file with glTF structure (should be called after writeBinData()).
0182   //! @param theDocument    [in] input document
0183   //! @param theRootLabels  [in] list of root shapes to export
0184   //! @param theLabelFilter [in] optional filter with document nodes to export
0185   //! @param theFileInfo    [in] map with file metadata to put into glTF header section
0186   //! @param theProgress    [in] optional progress indicator
0187   //! @return FALSE on file writing failure
0188   Standard_EXPORT virtual bool writeJson (const Handle(TDocStd_Document)& theDocument,
0189                                           const TDF_LabelSequence& theRootLabels,
0190                                           const TColStd_MapOfAsciiString* theLabelFilter,
0191                                           const TColStd_IndexedDataMapOfStringString& theFileInfo,
0192                                           const Message_ProgressRange& theProgress);
0193 
0194 protected:
0195 
0196   //! Return TRUE if face mesh should be skipped (e.g. because it is invalid or empty).
0197   Standard_EXPORT virtual Standard_Boolean toSkipFaceMesh (const RWMesh_FaceIterator& theFaceIter);
0198 
0199   //! Generate name for specified labels.
0200   //! @param[in] theFormat   name format to apply
0201   //! @param[in] theLabel    instance label
0202   //! @param[in] theRefLabel product label
0203   Standard_EXPORT virtual TCollection_AsciiString formatName (RWMesh_NameFormat theFormat,
0204                                                               const TDF_Label& theLabel,
0205                                                               const TDF_Label& theRefLabel) const;
0206 
0207   //! Write mesh nodes into binary file.
0208   //! @param theGltfFace [out] glTF face definition
0209   //! @param theBinFile  [out] output file to write into
0210   //! @param theFaceIter [in]  current face to write
0211   //! @param theAccessorNb [in] [out] last accessor index
0212   //! @param theMesh [in] [out] mesh
0213   Standard_EXPORT virtual void saveNodes (RWGltf_GltfFace& theGltfFace,
0214                                           std::ostream& theBinFile,
0215                                           const RWMesh_FaceIterator& theFaceIter,
0216                                           Standard_Integer& theAccessorNb,
0217                                           const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh) const;
0218 
0219   //! Write mesh normals into binary file.
0220   //! @param theGltfFace [out] glTF face definition
0221   //! @param theBinFile  [out] output file to write into
0222   //! @param theFaceIter [in]  current face to write
0223   //! @param theAccessorNb [in] [out] last accessor index
0224   //! @param theMesh [in] [out] mesh
0225   Standard_EXPORT virtual void saveNormals (RWGltf_GltfFace& theGltfFace,
0226                                             std::ostream& theBinFile,
0227                                             RWMesh_FaceIterator& theFaceIter,
0228                                             Standard_Integer& theAccessorNb,
0229                                             const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh) const;
0230 
0231   //! Write mesh texture UV coordinates into binary file.
0232   //! @param theGltfFace [out] glTF face definition
0233   //! @param theBinFile  [out] output file to write into
0234   //! @param theFaceIter [in]  current face to write
0235   //! @param theAccessorNb [in] [out] last accessor index
0236   //! @param theMesh [in] [out] mesh
0237   Standard_EXPORT virtual void saveTextCoords (RWGltf_GltfFace& theGltfFace,
0238                                                std::ostream& theBinFile,
0239                                                const RWMesh_FaceIterator& theFaceIter,
0240                                                Standard_Integer& theAccessorNb,
0241                                                const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh) const;
0242 
0243   //! Write mesh indexes into binary file.
0244   //! @param theGltfFace [out] glTF face definition
0245   //! @param theBinFile  [out] output file to write into
0246   //! @param theFaceIter [in]  current face to write
0247   //! @param theAccessorNb [in] [out] last accessor index
0248   //! @param theMesh [in] [out] mesh
0249   Standard_EXPORT virtual void saveIndices (RWGltf_GltfFace& theGltfFace,
0250                                             std::ostream& theBinFile,
0251                                             const RWMesh_FaceIterator& theFaceIter,
0252                                             Standard_Integer& theAccessorNb,
0253                                             const std::shared_ptr<RWGltf_CafWriter::Mesh>& theMesh);
0254 
0255 protected:
0256 
0257   //! Write bufferView for vertex positions within RWGltf_GltfRootElement_Accessors section
0258   //! @param theGltfFace [in] face definition to write
0259   Standard_EXPORT virtual void writePositions (const RWGltf_GltfFace& theGltfFace);
0260 
0261   //! Write bufferView for vertex normals within RWGltf_GltfRootElement_Accessors section
0262   //! @param theGltfFace [in] face definition to write
0263   Standard_EXPORT virtual void writeNormals (const RWGltf_GltfFace& theGltfFace);
0264 
0265   //! Write bufferView for vertex texture coordinates within RWGltf_GltfRootElement_Accessors section
0266   //! @param theGltfFace [in] face definition to write
0267   Standard_EXPORT virtual void writeTextCoords (const RWGltf_GltfFace& theGltfFace);
0268 
0269   //! Write bufferView for triangle indexes within RWGltf_GltfRootElement_Accessors section.
0270   //! @param theGltfFace [in] face definition to write
0271   Standard_EXPORT virtual void writeIndices (const RWGltf_GltfFace& theGltfFace);
0272 
0273 protected:
0274 
0275   //! Write RWGltf_GltfRootElement_Accessors section.
0276   //! @param theSceneNodeMap [in] ordered map of scene nodes
0277   Standard_EXPORT virtual void writeAccessors (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
0278 
0279   //! Write RWGltf_GltfRootElement_Animations section (reserved).
0280   Standard_EXPORT virtual void writeAnimations();
0281 
0282   //! Write RWGltf_GltfRootElement_Asset section.
0283   //! @param theFileInfo [in] optional metadata to write into file header
0284   Standard_EXPORT virtual void writeAsset (const TColStd_IndexedDataMapOfStringString& theFileInfo);
0285 
0286   //! Write RWGltf_GltfRootElement_BufferViews section.
0287   //! @param theBinDataBufferId [in] index of binary buffer with vertex data
0288   Standard_EXPORT virtual void writeBufferViews (const Standard_Integer theBinDataBufferId);
0289 
0290   //! Write RWGltf_GltfRootElement_Buffers section.
0291   Standard_EXPORT virtual void writeBuffers();
0292 
0293   //! Write RWGltf_GltfRootElement_ExtensionsUsed/RWGltf_GltfRootElement_ExtensionsRequired sections (reserved).
0294   Standard_EXPORT virtual void writeExtensions();
0295 
0296   //! Write RWGltf_GltfRootElement_Images section.
0297   //! @param theSceneNodeMap [in] ordered map of scene nodes
0298   //! @param theMaterialMap [out] map of materials, filled with image files used by textures
0299   Standard_EXPORT virtual void writeImages (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
0300 
0301   //! Write RWGltf_GltfRootElement_Materials section.
0302   //! @param theSceneNodeMap [in] ordered map of scene nodes
0303   //! @param theMaterialMap [out] map of materials, filled with materials
0304   Standard_EXPORT virtual void writeMaterials (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
0305 
0306   //! Write RWGltf_GltfRootElement_Meshes section.
0307   //! @param theSceneNodeMap [in] ordered map of scene nodes
0308   //! @param theMaterialMap  [in] map of materials
0309   Standard_EXPORT virtual void writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
0310 
0311   //! Write a primitive array to RWGltf_GltfRootElement_Meshes section.
0312   //! @param[in]     theGltfFace     face to write
0313   //! @param[in]     theName         primitive array name
0314   //! @param[in]     theDracoBufInd  draco buffer index 
0315   //! @param[in,out] theToStartPrims flag indicating that primitive array has been started
0316   Standard_EXPORT virtual void writePrimArray (const RWGltf_GltfFace& theGltfFace,
0317                                                const TCollection_AsciiString& theName,
0318                                                const int theDracoBufInd,
0319                                                bool& theToStartPrims);
0320 
0321   //! Write RWGltf_GltfRootElement_Nodes section.
0322   //! @param theDocument     [in] input document
0323   //! @param theRootLabels   [in] list of root shapes to export
0324   //! @param theLabelFilter  [in] optional filter with document nodes to export
0325   //! @param theSceneNodeMap [in] ordered map of scene nodes
0326   //! @param theSceneRootNodeInds [out] sequence of scene nodes pointing to root shapes (to be used for writeScenes())
0327   Standard_EXPORT virtual void writeNodes (const Handle(TDocStd_Document)&  theDocument,
0328                                            const TDF_LabelSequence&         theRootLabels,
0329                                            const TColStd_MapOfAsciiString*  theLabelFilter,
0330                                            const RWGltf_GltfSceneNodeMap&   theSceneNodeMap,
0331                                            NCollection_Sequence<Standard_Integer>& theSceneRootNodeInds);
0332 
0333   //! Write RWGltf_GltfRootElement_Samplers section.
0334   Standard_EXPORT virtual void writeSamplers();
0335 
0336   //! Write RWGltf_GltfRootElement_Scene section.
0337   //! @param theDefSceneId [in] index of default scene (0)
0338   Standard_EXPORT virtual void writeScene (const Standard_Integer theDefSceneId);
0339 
0340   //! Write RWGltf_GltfRootElement_Scenes section.
0341   //! @param theSceneRootNodeInds [in] sequence of scene nodes pointing to root shapes
0342   Standard_EXPORT virtual void writeScenes (const NCollection_Sequence<Standard_Integer>& theSceneRootNodeInds);
0343 
0344   //! Write RWGltf_GltfRootElement_Skins section (reserved).
0345   Standard_EXPORT virtual void writeSkins();
0346 
0347   //! Write RWGltf_GltfRootElement_Textures section.
0348   //! @param theSceneNodeMap [in] ordered map of scene nodes
0349   //! @param theMaterialMap [out] map of materials, filled with textures
0350   Standard_EXPORT virtual void writeTextures (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
0351 
0352 protected:
0353 
0354   //! Shape + Style pair.
0355   struct RWGltf_StyledShape
0356   {
0357     TopoDS_Shape  Shape;
0358     XCAFPrs_Style Style;
0359 
0360     RWGltf_StyledShape()
0361     {}
0362     explicit RWGltf_StyledShape(const TopoDS_Shape& theShape) : Shape(theShape)
0363     {}
0364     explicit RWGltf_StyledShape(const TopoDS_Shape& theShape,
0365                                 const XCAFPrs_Style& theStyle) : Shape(theShape), Style(theStyle)
0366     {}
0367     bool operator==(const RWGltf_StyledShape& theStyledShape) const
0368     {
0369       return Shape.IsSame(theStyledShape.Shape)
0370         && Style.IsEqual(theStyledShape.Style);
0371     }
0372   };
0373 
0374   struct Hasher
0375   {
0376     size_t operator()(const RWGltf_StyledShape& theShape) const noexcept
0377     {
0378       return std::hash<TopoDS_Shape>{}(theShape.Shape);
0379     }
0380 
0381     bool operator()(const RWGltf_StyledShape& theShape1,
0382                     const RWGltf_StyledShape& theShape2) const noexcept
0383     {
0384       return theShape1 == theShape2;
0385     }
0386   };
0387 
0388   typedef NCollection_IndexedDataMap<RWGltf_StyledShape, Handle(RWGltf_GltfFaceList), Hasher> ShapeToGltfFaceMap;
0389 
0390 protected:
0391 
0392   TCollection_AsciiString                       myFile;              //!< output glTF file
0393   TCollection_AsciiString                       myBinFileNameFull;   //!< output file with binary data (full  path)
0394   TCollection_AsciiString                       myBinFileNameShort;  //!< output file with binary data (short path)
0395   RWGltf_WriterTrsfFormat                       myTrsfFormat;        //!< transformation format to write into glTF file
0396   RWMesh_NameFormat                             myNodeNameFormat;    //!< name format for exporting Nodes
0397   RWMesh_NameFormat                             myMeshNameFormat;    //!< name format for exporting Meshes
0398   Standard_Boolean                              myIsBinary;          //!< flag to write into binary glTF format (.glb)
0399   Standard_Boolean                              myIsForcedUVExport;  //!< export UV coordinates even if there are no mapped texture
0400   Standard_Boolean                              myToEmbedTexturesInGlb; //!< flag to write image textures into GLB file
0401   Standard_Boolean                              myToMergeFaces;      //!< flag to merge faces within a single part
0402   Standard_Boolean                              myToSplitIndices16;  //!< flag to prefer keeping 16-bit indexes while merging face
0403   RWMesh_CoordinateSystemConverter              myCSTrsf;            //!< transformation from OCCT to glTF coordinate system
0404   XCAFPrs_Style                                 myDefaultStyle;      //!< default material definition to be used for nodes with only color defined
0405 
0406   std::shared_ptr<RWGltf_GltfOStreamWriter>     myWriter;            //!< JSON writer
0407   Handle(RWGltf_GltfMaterialMap)                myMaterialMap;       //!< map of defined materials
0408   RWGltf_GltfBufferView                         myBuffViewPos;       //!< current buffer view with nodes positions
0409   RWGltf_GltfBufferView                         myBuffViewNorm;      //!< current buffer view with nodes normals
0410   RWGltf_GltfBufferView                         myBuffViewTextCoord; //!< current buffer view with nodes UV coordinates
0411   RWGltf_GltfBufferView                         myBuffViewInd;       //!< current buffer view with triangulation indexes
0412   ShapeToGltfFaceMap                            myBinDataMap;        //!< map for TopoDS_Face to glTF face (merging duplicates)
0413   int64_t                                       myBinDataLen64;      //!< length of binary file
0414 
0415   std::vector<RWGltf_GltfBufferView>            myBuffViewsDraco;    //!< vector of buffers view with compression data
0416   Standard_Boolean                              myToParallel;        //!< flag to use multithreading; FALSE by default
0417   RWGltf_DracoParameters                        myDracoParameters;   //!< Draco parameters
0418 };
0419 
0420 #endif // _RWGltf_CafWriter_HeaderFiler