1 // Copyright (c) 2017-2019 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #ifndef _RWGltf_CafWriter_HeaderFiler
15 #define _RWGltf_CafWriter_HeaderFiler
17 #include <TColStd_IndexedDataMapOfStringString.hxx>
18 #include <TColStd_MapOfAsciiString.hxx>
19 #include <TDF_LabelSequence.hxx>
20 #include <TopTools_ShapeMapHasher.hxx>
21 #include <RWGltf_GltfBufferView.hxx>
22 #include <RWGltf_GltfFace.hxx>
23 #include <RWGltf_WriterTrsfFormat.hxx>
24 #include <RWMesh_CoordinateSystemConverter.hxx>
25 #include <RWMesh_NameFormat.hxx>
26 #include <XCAFPrs_Style.hxx>
30 class Message_ProgressRange;
31 class RWMesh_FaceIterator;
32 class RWGltf_GltfOStreamWriter;
33 class RWGltf_GltfMaterialMap;
34 class RWGltf_GltfSceneNodeMap;
35 class TDocStd_Document;
37 //! glTF writer context from XCAF document.
38 class RWGltf_CafWriter : public Standard_Transient
40 DEFINE_STANDARD_RTTIEXT(RWGltf_CafWriter, Standard_Transient)
44 //! @param theFile [in] path to output glTF file
45 //! @param theIsBinary [in] flag to write into binary glTF format (.glb)
46 Standard_EXPORT RWGltf_CafWriter (const TCollection_AsciiString& theFile,
47 Standard_Boolean theIsBinary);
50 Standard_EXPORT virtual ~RWGltf_CafWriter();
52 //! Return transformation from OCCT to glTF coordinate system.
53 const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCSTrsf; }
55 //! Return transformation from OCCT to glTF coordinate system.
56 RWMesh_CoordinateSystemConverter& ChangeCoordinateSystemConverter() { return myCSTrsf; }
58 //! Set transformation from OCCT to glTF coordinate system.
59 void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCSTrsf = theConverter; }
61 //! Return flag to write into binary glTF format (.glb), specified within class constructor.
62 bool IsBinary() const { return myIsBinary; }
64 //! Return preferred transformation format for writing into glTF file; RWGltf_WriterTrsfFormat_Compact by default.
65 RWGltf_WriterTrsfFormat TransformationFormat() const { return myTrsfFormat; }
67 //! Set preferred transformation format for writing into glTF file.
68 void SetTransformationFormat (RWGltf_WriterTrsfFormat theFormat) { myTrsfFormat = theFormat; }
70 //! Return name format for exporting Nodes; RWMesh_NameFormat_InstanceOrProduct by default.
71 RWMesh_NameFormat NodeNameFormat() const { return myNodeNameFormat; }
73 //! Set name format for exporting Nodes.
74 void SetNodeNameFormat (RWMesh_NameFormat theFormat) { myNodeNameFormat = theFormat; }
76 //! Return name format for exporting Meshes; RWMesh_NameFormat_Product by default.
77 RWMesh_NameFormat MeshNameFormat() const { return myMeshNameFormat; }
79 //! Set name format for exporting Meshes.
80 void SetMeshNameFormat (RWMesh_NameFormat theFormat) { myMeshNameFormat = theFormat; }
82 //! Return TRUE to export UV coordinates even if there are no mapped texture; FALSE by default.
83 bool IsForcedUVExport() const { return myIsForcedUVExport; }
85 //! Set flag to export UV coordinates even if there are no mapped texture; FALSE by default.
86 void SetForcedUVExport (bool theToForce) { myIsForcedUVExport = theToForce; }
88 //! Return default material definition to be used for nodes with only color defined.
89 const XCAFPrs_Style& DefaultStyle() const { return myDefaultStyle; }
91 //! Set default material definition to be used for nodes with only color defined.
92 void SetDefaultStyle (const XCAFPrs_Style& theStyle) { myDefaultStyle = theStyle; }
94 //! Return flag to write image textures into GLB file (binary gltf export); TRUE by default.
95 //! When set to FALSE, texture images will be written as separate files.
96 //! Has no effect on writing into non-binary format.
97 Standard_Boolean ToEmbedTexturesInGlb() { return myToEmbedTexturesInGlb; }
99 //! Set flag to write image textures into GLB file (binary gltf export).
100 void SetToEmbedTexturesInGlb (Standard_Boolean theToEmbedTexturesInGlb) { myToEmbedTexturesInGlb = theToEmbedTexturesInGlb; }
102 //! Return flag to merge faces within a single part; FALSE by default.
103 bool ToMergeFaces() const { return myToMergeFaces; }
105 //! Set flag to merge faces within a single part.
106 //! May reduce JSON size thanks to smaller number of primitive arrays.
107 void SetMergeFaces (bool theToMerge) { myToMergeFaces = theToMerge; }
109 //! Return flag to prefer keeping 16-bit indexes while merging face; FALSE by default.
110 bool ToSplitIndices16() const { return myToSplitIndices16; }
112 //! Set flag to prefer keeping 16-bit indexes while merging face.
113 //! Has effect only with ToMergeFaces() option turned ON.
114 //! May reduce binary data size thanks to smaller triangle indexes.
115 void SetSplitIndices16 (bool theToSplit) { myToSplitIndices16 = theToSplit; }
117 //! Write glTF file and associated binary file.
118 //! Triangulation data should be precomputed within shapes!
119 //! @param theDocument [in] input document
120 //! @param theRootLabels [in] list of root shapes to export
121 //! @param theLabelFilter [in] optional filter with document nodes to export,
122 //! with keys defined by XCAFPrs_DocumentExplorer::DefineChildId() and filled recursively
123 //! (leaves and parent assembly nodes at all levels);
124 //! when not NULL, all nodes not included into the map will be ignored
125 //! @param theFileInfo [in] map with file metadata to put into glTF header section
126 //! @param theProgress [in] optional progress indicator
127 //! @return FALSE on file writing failure
128 Standard_EXPORT virtual bool Perform (const Handle(TDocStd_Document)& theDocument,
129 const TDF_LabelSequence& theRootLabels,
130 const TColStd_MapOfAsciiString* theLabelFilter,
131 const TColStd_IndexedDataMapOfStringString& theFileInfo,
132 const Message_ProgressRange& theProgress);
134 //! Write glTF file and associated binary file.
135 //! Triangulation data should be precomputed within shapes!
136 //! @param theDocument [in] input document
137 //! @param theFileInfo [in] map with file metadata to put into glTF header section
138 //! @param theProgress [in] optional progress indicator
139 //! @return FALSE on file writing failure
140 Standard_EXPORT virtual bool Perform (const Handle(TDocStd_Document)& theDocument,
141 const TColStd_IndexedDataMapOfStringString& theFileInfo,
142 const Message_ProgressRange& theProgress);
146 //! Write binary data file with triangulation data.
147 //! Triangulation data should be precomputed within shapes!
148 //! @param theDocument [in] input document
149 //! @param theRootLabels [in] list of root shapes to export
150 //! @param theLabelFilter [in] optional filter with document nodes to export
151 //! @param theProgress [in] optional progress indicator
152 //! @return FALSE on file writing failure
153 Standard_EXPORT virtual bool writeBinData (const Handle(TDocStd_Document)& theDocument,
154 const TDF_LabelSequence& theRootLabels,
155 const TColStd_MapOfAsciiString* theLabelFilter,
156 const Message_ProgressRange& theProgress);
158 //! Write JSON file with glTF structure (should be called after writeBinData()).
159 //! @param theDocument [in] input document
160 //! @param theRootLabels [in] list of root shapes to export
161 //! @param theLabelFilter [in] optional filter with document nodes to export
162 //! @param theFileInfo [in] map with file metadata to put into glTF header section
163 //! @param theProgress [in] optional progress indicator
164 //! @return FALSE on file writing failure
165 Standard_EXPORT virtual bool writeJson (const Handle(TDocStd_Document)& theDocument,
166 const TDF_LabelSequence& theRootLabels,
167 const TColStd_MapOfAsciiString* theLabelFilter,
168 const TColStd_IndexedDataMapOfStringString& theFileInfo,
169 const Message_ProgressRange& theProgress);
173 //! Return TRUE if face mesh should be skipped (e.g. because it is invalid or empty).
174 Standard_EXPORT virtual Standard_Boolean toSkipFaceMesh (const RWMesh_FaceIterator& theFaceIter);
176 //! Generate name for specified labels.
177 //! @param[in] theFormat name format to apply
178 //! @param[in] theLabel instance label
179 //! @param[in] theRefLabel product label
180 Standard_EXPORT virtual TCollection_AsciiString formatName (RWMesh_NameFormat theFormat,
181 const TDF_Label& theLabel,
182 const TDF_Label& theRefLabel) const;
184 //! Write mesh nodes into binary file.
185 //! @param theGltfFace [out] glTF face definition
186 //! @param theBinFile [out] output file to write into
187 //! @param theFaceIter [in] current face to write
188 //! @param theAccessorNb [in] [out] last accessor index
189 Standard_EXPORT virtual void saveNodes (RWGltf_GltfFace& theGltfFace,
190 std::ostream& theBinFile,
191 const RWMesh_FaceIterator& theFaceIter,
192 Standard_Integer& theAccessorNb) const;
194 //! Write mesh normals into binary file.
195 //! @param theGltfFace [out] glTF face definition
196 //! @param theBinFile [out] output file to write into
197 //! @param theFaceIter [in] current face to write
198 //! @param theAccessorNb [in] [out] last accessor index
199 Standard_EXPORT virtual void saveNormals (RWGltf_GltfFace& theGltfFace,
200 std::ostream& theBinFile,
201 RWMesh_FaceIterator& theFaceIter,
202 Standard_Integer& theAccessorNb) const;
204 //! Write mesh texture UV coordinates into binary file.
205 //! @param theGltfFace [out] glTF face definition
206 //! @param theBinFile [out] output file to write into
207 //! @param theFaceIter [in] current face to write
208 //! @param theAccessorNb [in] [out] last accessor index
209 Standard_EXPORT virtual void saveTextCoords (RWGltf_GltfFace& theGltfFace,
210 std::ostream& theBinFile,
211 const RWMesh_FaceIterator& theFaceIter,
212 Standard_Integer& theAccessorNb) const;
214 //! Write mesh indexes into binary file.
215 //! @param theGltfFace [out] glTF face definition
216 //! @param theBinFile [out] output file to write into
217 //! @param theFaceIter [in] current face to write
218 //! @param theAccessorNb [in] [out] last accessor index
219 Standard_EXPORT virtual void saveIndices (RWGltf_GltfFace& theGltfFace,
220 std::ostream& theBinFile,
221 const RWMesh_FaceIterator& theFaceIter,
222 Standard_Integer& theAccessorNb);
226 //! Write bufferView for vertex positions within RWGltf_GltfRootElement_Accessors section
227 //! @param theGltfFace [in] face definition to write
228 Standard_EXPORT virtual void writePositions (const RWGltf_GltfFace& theGltfFace);
230 //! Write bufferView for vertex normals within RWGltf_GltfRootElement_Accessors section
231 //! @param theGltfFace [in] face definition to write
232 Standard_EXPORT virtual void writeNormals (const RWGltf_GltfFace& theGltfFace);
234 //! Write bufferView for vertex texture coordinates within RWGltf_GltfRootElement_Accessors section
235 //! @param theGltfFace [in] face definition to write
236 Standard_EXPORT virtual void writeTextCoords (const RWGltf_GltfFace& theGltfFace);
238 //! Write bufferView for triangle indexes within RWGltf_GltfRootElement_Accessors section.
239 //! @param theGltfFace [in] face definition to write
240 Standard_EXPORT virtual void writeIndices (const RWGltf_GltfFace& theGltfFace);
244 //! Write RWGltf_GltfRootElement_Accessors section.
245 //! @param theSceneNodeMap [in] ordered map of scene nodes
246 Standard_EXPORT virtual void writeAccessors (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
248 //! Write RWGltf_GltfRootElement_Animations section (reserved).
249 Standard_EXPORT virtual void writeAnimations();
251 //! Write RWGltf_GltfRootElement_Asset section.
252 //! @param theFileInfo [in] optional metadata to write into file header
253 Standard_EXPORT virtual void writeAsset (const TColStd_IndexedDataMapOfStringString& theFileInfo);
255 //! Write RWGltf_GltfRootElement_BufferViews section.
256 //! @param theBinDataBufferId [in] index of binary buffer with vertex data
257 Standard_EXPORT virtual void writeBufferViews (const Standard_Integer theBinDataBufferId);
259 //! Write RWGltf_GltfRootElement_Buffers section.
260 Standard_EXPORT virtual void writeBuffers();
262 //! Write RWGltf_GltfRootElement_ExtensionsUsed/RWGltf_GltfRootElement_ExtensionsRequired sections (reserved).
263 Standard_EXPORT virtual void writeExtensions();
265 //! Write RWGltf_GltfRootElement_Images section.
266 //! @param theSceneNodeMap [in] ordered map of scene nodes
267 //! @param theMaterialMap [out] map of materials, filled with image files used by textures
268 Standard_EXPORT virtual void writeImages (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
270 //! Write RWGltf_GltfRootElement_Materials section.
271 //! @param theSceneNodeMap [in] ordered map of scene nodes
272 //! @param theMaterialMap [out] map of materials, filled with materials
273 Standard_EXPORT virtual void writeMaterials (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
275 //! Write RWGltf_GltfRootElement_Meshes section.
276 //! @param theSceneNodeMap [in] ordered map of scene nodes
277 //! @param theMaterialMap [in] map of materials
278 Standard_EXPORT virtual void writeMeshes (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
280 //! Write a primitive array to RWGltf_GltfRootElement_Meshes section.
281 //! @param[in] theGltfFace face to write
282 //! @param[in] theName primitive array name
283 //! @param[in,out] theToStartPrims flag indicating that primitive array has been started
284 Standard_EXPORT virtual void writePrimArray (const RWGltf_GltfFace& theGltfFace,
285 const TCollection_AsciiString& theName,
286 bool& theToStartPrims);
288 //! Write RWGltf_GltfRootElement_Nodes section.
289 //! @param theDocument [in] input document
290 //! @param theRootLabels [in] list of root shapes to export
291 //! @param theLabelFilter [in] optional filter with document nodes to export
292 //! @param theSceneNodeMap [in] ordered map of scene nodes
293 //! @param theSceneRootNodeInds [out] sequence of scene nodes pointing to root shapes (to be used for writeScenes())
294 Standard_EXPORT virtual void writeNodes (const Handle(TDocStd_Document)& theDocument,
295 const TDF_LabelSequence& theRootLabels,
296 const TColStd_MapOfAsciiString* theLabelFilter,
297 const RWGltf_GltfSceneNodeMap& theSceneNodeMap,
298 NCollection_Sequence<Standard_Integer>& theSceneRootNodeInds);
300 //! Write RWGltf_GltfRootElement_Samplers section.
301 Standard_EXPORT virtual void writeSamplers();
303 //! Write RWGltf_GltfRootElement_Scene section.
304 //! @param theDefSceneId [in] index of default scene (0)
305 Standard_EXPORT virtual void writeScene (const Standard_Integer theDefSceneId);
307 //! Write RWGltf_GltfRootElement_Scenes section.
308 //! @param theSceneRootNodeInds [in] sequence of scene nodes pointing to root shapes
309 Standard_EXPORT virtual void writeScenes (const NCollection_Sequence<Standard_Integer>& theSceneRootNodeInds);
311 //! Write RWGltf_GltfRootElement_Skins section (reserved).
312 Standard_EXPORT virtual void writeSkins();
314 //! Write RWGltf_GltfRootElement_Textures section.
315 //! @param theSceneNodeMap [in] ordered map of scene nodes
316 //! @param theMaterialMap [out] map of materials, filled with textures
317 Standard_EXPORT virtual void writeTextures (const RWGltf_GltfSceneNodeMap& theSceneNodeMap);
321 //! Shape + Style pair.
322 struct RWGltf_StyledShape
327 RWGltf_StyledShape() {}
328 explicit RWGltf_StyledShape (const TopoDS_Shape& theShape) : Shape (theShape) {}
329 explicit RWGltf_StyledShape (const TopoDS_Shape& theShape,
330 const XCAFPrs_Style& theStyle) : Shape (theShape), Style (theStyle) {}
332 //! Computes a hash code.
333 static Standard_Integer HashCode (const RWGltf_StyledShape& theShape, Standard_Integer theUpperBound)
335 return theShape.Shape.HashCode (theUpperBound);
337 //! Equality comparison.
338 static Standard_Boolean IsEqual (const RWGltf_StyledShape& theS1, const RWGltf_StyledShape& theS2)
340 return theS1.Shape.IsSame (theS2.Shape)
341 && theS1.Style.IsEqual(theS2.Style);
345 typedef NCollection_IndexedDataMap<RWGltf_StyledShape, Handle(RWGltf_GltfFaceList), RWGltf_StyledShape> ShapeToGltfFaceMap;
349 TCollection_AsciiString myFile; //!< output glTF file
350 TCollection_AsciiString myBinFileNameFull; //!< output file with binary data (full path)
351 TCollection_AsciiString myBinFileNameShort; //!< output file with binary data (short path)
352 RWGltf_WriterTrsfFormat myTrsfFormat; //!< transformation format to write into glTF file
353 RWMesh_NameFormat myNodeNameFormat; //!< name format for exporting Nodes
354 RWMesh_NameFormat myMeshNameFormat; //!< name format for exporting Meshes
355 Standard_Boolean myIsBinary; //!< flag to write into binary glTF format (.glb)
356 Standard_Boolean myIsForcedUVExport; //!< export UV coordinates even if there are no mapped texture
357 Standard_Boolean myToEmbedTexturesInGlb; //!< flag to write image textures into GLB file
358 Standard_Boolean myToMergeFaces; //!< flag to merge faces within a single part
359 Standard_Boolean myToSplitIndices16; //!< flag to prefer keeping 16-bit indexes while merging face
360 RWMesh_CoordinateSystemConverter myCSTrsf; //!< transformation from OCCT to glTF coordinate system
361 XCAFPrs_Style myDefaultStyle; //!< default material definition to be used for nodes with only color defined
363 opencascade::std::shared_ptr<RWGltf_GltfOStreamWriter>
364 myWriter; //!< JSON writer
365 Handle(RWGltf_GltfMaterialMap) myMaterialMap; //!< map of defined materials
366 RWGltf_GltfBufferView myBuffViewPos; //!< current buffer view with nodes positions
367 RWGltf_GltfBufferView myBuffViewNorm; //!< current buffer view with nodes normals
368 RWGltf_GltfBufferView myBuffViewTextCoord; //!< current buffer view with nodes UV coordinates
369 RWGltf_GltfBufferView myBuffViewInd; //!< current buffer view with triangulation indexes
370 ShapeToGltfFaceMap myBinDataMap; //!< map for TopoDS_Face to glTF face (merging duplicates)
371 int64_t myBinDataLen64; //!< length of binary file
375 #endif // _RWGltf_CafWriter_HeaderFiler