HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_IO.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_IO.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #pragma once
12 
13 #ifndef __GA_IO__
14 #define __GA_IO__
15 
16 #include "GA_API.h"
17 #include "GA_Types.h"
18 
19 #include <SYS/SYS_Types.h>
20 
21 #include <iosfwd>
22 
23 
24 class GA_Detail;
25 class GA_LoadMap;
26 class GA_SaveMap;
27 class GA_Stat;
28 
29 class FS_Reader;
30 class FS_Writer;
31 class UT_Options;
32 class UT_IStream;
33 class UT_JSONParser;
34 class UT_JSONWriter;
35 class UT_StringArray;
36 class UT_SCFReader;
37 class GA_SaveOptions;
38 class GA_LoadOptions;
39 
40 
41 /// @brief Class which defines an I/O interface to save/load geometry
42 ///
43 /// Loading a GA_Detail from a disk file goes through the following process
44 /// @code
45 /// GA_Detail::load(const char *filename, const GA_LoadOptions *opts)
46 /// foreach (IO) {
47 /// if (IO->checkFilename(filename, opts) &&
48 /// IO->readFile(*this, filename, opts))
49 /// {
50 /// return true;
51 /// }
52 /// }
53 /// GA_IO::io_ReadHandle io(IO, filename, errors);
54 /// if (io.isValid())
55 /// return load(*io.getStream(), options);
56 /// return false;
57 /// @endcode
58 /// Loading a GA_Detail from a stream goes through a similar process
59 /// @code
60 /// GA_Detail::load(UT_IStream &is, const GA_LoadOptions *opts):
61 /// uint8 magic = is.peek();
62 /// foreach (IO) {
63 /// if (IO->checkByteMagic(magic) && IO->readFile(*this, is, opts))
64 /// return true;
65 /// }
66 /// return false;
67 /// @endcode
68 ///
69 /// Saving geometry works similarly: @code
70 /// GA_Detail::save(const char *filename, const GA_SaveOptions *opts):
71 /// foreach (IO) {
72 /// if (IO->checkFilename(filename, opts))
73 /// return IO->writeFile(*this, filename, opts);
74 /// }
75 /// return false;
76 ///
77 /// GA_Detail::save(ostream &os, const GA_SaveOptions *opts) const
78 /// IO = selectIO(opts);
79 /// return IO->writeStream(*this, os, opts);
80 ///
81 class GA_API GA_IO
82 {
83 public:
84  GA_IO();
85  virtual ~GA_IO();
86 
87  /// @{
88  /// Return identifiers for the file format.
89  virtual const char *getToken() const = 0;
90  virtual const char *getLabel() const = 0;
91  /// @}
92 
93  /// @{
94  /// Check whether the filename could be handled by this IO handler.
95  /// This is called on both load and save operations.
96  virtual bool checkFilename(const char *filename,
97  const GA_SaveOptions *opts) const = 0;
98  virtual bool checkFilename(const char *filename,
99  const GA_LoadOptions *opts) const = 0;
100  /// @}
101 
102  /// When loading an un-named stream, check whether the first byte of the
103  /// stream is an indicator of the file format. This is only called for
104  /// loading.
105  virtual bool checkByteMagic(uint8 first_byte,
106  const GA_LoadOptions *opts) const = 0;
107 
108  /// Stat a disk file without necessarily loading the entire geometry
109  virtual bool statFile(const char *filename,
110  GA_Stat &stat, uint stat_level) const;
111  /// Stat a stream
112  virtual bool statStream(UT_IStream &is,
113  GA_Stat &stat, uint stat_level) const = 0;
114 
115  /// Load geometry from a disk file. The default behaviour for this method
116  /// is: @code
117  /// GA_IO::io_ReadHandle io(filename, true);
118  /// return (io.isValid()) ? readStream(g, *io.getStream(), opts) : false;
119  /// @endcode
120  virtual bool readFile(GA_Detail &g,
121  const char *filename,
122  const GA_LoadOptions *opts,
123  UT_StringArray *errors) const;
124 
125  /// Load geometry from an input stream.
126  virtual bool readStream(GA_Detail &g,
127  UT_IStream &is,
128  const GA_LoadOptions *opts,
129  UT_StringArray *errors) const = 0;
130 
131  /// Save geometry to a disk file. The default behaviour for this method is:
132  /// @code
133  /// GA_IO::io_WriteHandle io(filename, true);
134  /// return io.isValid() ? writeStream(g, *io.getStream(), opts) : false;
135  /// @endcode
136  virtual bool writeFile(const GA_Detail &g,
137  const char *filename,
138  const GA_SaveOptions *opts,
139  UT_StringArray *errors) const;
140 
141  /// Write geometry to an output stream
142  virtual bool writeStream(const GA_Detail &g,
143  std::ostream &os,
144  bool binary,
145  const GA_SaveOptions *opts,
146  UT_StringArray *errors) const = 0;
147 
148  /// Create and initialize a private info attribute, stored as a JSON
149  /// encoded UT_Options object in a string attribute.
150  static bool createInfoAttribute(
151  GA_Detail &g, const char *attrib_name,
152  const char *format_token,
153  const UT_Options *from_file);
154 
155  /// Extract a UT_Options object from an attribute storing a JSON encoding.
156  static bool retrieveInfo(const GA_Detail &g,
157  const char *attrib_name,
158  UT_Options &info);
159 
160  /// Destroy the private info attribute created by createInfoAttribute().
161  static bool destroyInfoAttribute(GA_Detail &g,
162  const char *attrib_name);
163 
164 protected:
165  /// If the io_ReadHandle should scan for filenames starting with "stdin",
166  /// this method should return true.
167  virtual bool readCheckStdin() const { return false; }
168  /// If the io_ReadHandle should scan for filenames ending with
169  /// extensions that indicate it is compressed then this method
170  /// should return true
171  virtual bool readCheckCompressed() const = 0;
172  /// If the io_WriteHandle should scan for filenames starting with "stdout",
173  /// this method should return true.
174  virtual bool writeCheckStdout() const { return false; }
175 
176  bool isStdout(const char *filename) const;
177 
178  /// Class to hold information about a read stream. This class is used
179  /// solely to hold the istream handles and clean up properly.
180  /// Destruction of the class will close the stream
181  /// @note The io_ReadHandle will automatically search the
182  /// HOUDINI_GEOMETRY_PATH when scanning for disk files.
183  /// @note If the filename ends in .gz, or .sc the appropriate decompression
184  /// stream wil be allocated
186  {
187  public:
189  : myStream(nullptr)
190  , myBaseStream(nullptr)
191  , myReader(nullptr)
192  , myIsStdin(false)
193  , myScfReader(nullptr)
194  , myIsScf(false)
195  {}
196  io_ReadHandle(const GA_IO &io,
197  const char *filename,
198  UT_StringArray *errors)
199  : myStream(nullptr)
200  , myBaseStream(nullptr)
201  , myReader(nullptr)
202  , myIsStdin(false)
203  , myScfReader(nullptr)
204  , myIsScf(false)
205  {
206  open(io, filename, errors);
207  }
209  {
210  close();
211  }
212 
213  /// Test whether the read handle is valid
214  bool isValid() const { return myStream != nullptr; }
215  /// Test whether the read handle reads from stdin
216  bool isStdin() const { return myIsStdin; }
217  /// Get the UT_IStream associated with the handle
218  UT_IStream *getStream() const { return myStream; }
219  /// Open a file for reading. If @c check_stdin is true and the
220  /// filename starts with "stdin", the stream returned will be stdin.
221  /// If the open fails, errors will be appended to the error array.
222  UT_IStream *open(const GA_IO &io, const char *filename,
223  UT_StringArray *errors);
224  /// Close the stream
225  void close();
226 
227  /// Provide access to the FS_Reader (this may be nullptr)
228  const FS_Reader *reader() const { return myReader; }
229  private:
230  UT_IStream *myStream;
231  UT_IStream *myBaseStream;
232  FS_Reader *myReader;
233  bool myIsStdin;
234  UT_SCFReader *myScfReader;
235  bool myIsScf;
236  };
237 
238  /// Class to hold information about a write stream. This class is used
239  /// solely to hold the ostream handles and clean up properly.
240  /// Destruction of the class will close the stream.
242  {
243  public:
245  : myStream(nullptr)
246  , myWriter(nullptr)
247  {
248  }
249  io_WriteHandle(const GA_IO &io, const char *filename,
250  UT_StringArray *errors)
251  : myStream(nullptr)
252  , myWriter(nullptr)
253  {
254  open(io, filename, errors);
255  }
257  {
258  close();
259  }
260 
261  /// Check if the stream is valid
262  bool isValid() const { return myStream != nullptr; }
263  /// Get the output stream
264  std::ostream *getStream() const { return myStream; }
265  /// Open a file for reading. If @c check_stdout is true and the
266  /// filename starts with "stdout", the stream returned will be stdout.
267  /// If the open fails, errors will be appended to the error array.
268  std::ostream *open(const GA_IO &io, const char *filename,
269  UT_StringArray *errors);
270  /// Close the stream
271  void close();
272  private:
273  std::ostream *myStream;
274  FS_Writer *myWriter;
275  };
276 
277  /// Provide access to private portions of the GA_Detail class for loading
278  /// Tell the detail that the loading will be adding @c npoints, @c nvertex
279  /// and @c nprimitive primitives. This will adjust the load map so that
280  /// the proper index/offset mappings can be created. It also adjusts the
281  /// index maps.
282  /// The method will return false if there was an error.
283  bool setLoadCounts(GA_Detail &gdp,
284  GA_Size npoints,
285  GA_Size nvertex,
286  GA_Size nprimitive,
287  GA_LoadMap &loadmap) const;
288 
289  /// @{
290  /// Save and load the vertex point-reference array using JSON
291  /// @warning: After calling jsonLoadPointReference() you must rebuild the
292  /// topology attributes.
293  bool jsonSavePointReference(const GA_Detail &gdp,
294  UT_JSONWriter &w,
295  const GA_SaveMap &savemap) const;
297  UT_JSONParser &p,
298  const GA_LoadMap &loadmap) const;
299  /// @}
300 
301  /// After the geometry has been loaded, the sub-class may need to call the
302  /// method to rebuild the topology attributes on the detail. The caller
303  /// may also request that full topology attributes are created after load.
304  ///
305  /// If the method fails, it's because the geometry failed the sanity check
306  /// on topology. In this case, the geometry is cleared. The user should
307  /// probably add an error in this case.
308  //
309  /// @warning This method is for advanced users.
310  bool rebuildTopology(GA_Detail &gdp,
311  bool create_attributes=false) const;
312 };
313 
314 #endif
315 
Class for reading files.
Definition: FS_Reader.h:33
bool isValid() const
Check if the stream is valid.
Definition: GA_IO.h:262
const FS_Reader * reader() const
Provide access to the FS_Reader (this may be nullptr)
Definition: GA_IO.h:228
GT_API const UT_StringHolder filename
bool setLoadCounts(GA_Detail &gdp, GA_Size npoints, GA_Size nvertex, GA_Size nprimitive, GA_LoadMap &loadmap) const
UT_IStream * getStream() const
Get the UT_IStream associated with the handle.
Definition: GA_IO.h:218
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
GLboolean GLboolean g
Definition: glcorearb.h:1222
virtual bool readCheckCompressed() const =0
virtual bool writeCheckStdout() const
Definition: GA_IO.h:174
virtual bool writeStream(const GA_Detail &g, std::ostream &os, bool binary, const GA_SaveOptions *opts, UT_StringArray *errors) const =0
Write geometry to an output stream.
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:87
io_WriteHandle()
Definition: GA_IO.h:244
#define GA_API
Definition: GA_API.h:14
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
void close() override
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
std::ostream * getStream() const
Get the output stream.
Definition: GA_IO.h:264
unsigned char uint8
Definition: SYS_Types.h:36
bool isValid() const
Test whether the read handle is valid.
Definition: GA_IO.h:214
int open(float queuesize) override
io_ReadHandle(const GA_IO &io, const char *filename, UT_StringArray *errors)
Definition: GA_IO.h:196
~io_ReadHandle()
Definition: GA_IO.h:208
Class for writing files.
Definition: FS_Writer.h:32
Options during loading.
Definition: GA_LoadMap.h:42
io_ReadHandle()
Definition: GA_IO.h:188
virtual bool writeFile(const GA_Detail &g, const char *filename, const GA_SaveOptions *opts, UT_StringArray *errors) const
bool jsonSavePointReference(const GA_Detail &gdp, UT_JSONWriter &w, const GA_SaveMap &savemap) const
bool rebuildTopology(GA_Detail &gdp, bool create_attributes=false) const
virtual bool readStream(GA_Detail &g, UT_IStream &is, const GA_LoadOptions *opts, UT_StringArray *errors) const =0
Load geometry from an input stream.
A map of string to various well defined value types.
Definition: UT_Options.h:84
Class to return information about a GA_Detail.
Definition: GA_Stat.h:50
bool isStdout(const char *filename) const
io_WriteHandle(const GA_IO &io, const char *filename, UT_StringArray *errors)
Definition: GA_IO.h:249
virtual bool readFile(GA_Detail &g, const char *filename, const GA_LoadOptions *opts, UT_StringArray *errors) const
Class which defines an I/O interface to save/load geometry.
Container class for all geometry.
Definition: GA_Detail.h:96
Interface for reading Seekable Compressed Format (SCF) files.
Definition: UT_SCFReader.h:21
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
virtual bool readCheckStdin() const
Definition: GA_IO.h:167
~io_WriteHandle()
Definition: GA_IO.h:256
Class to specify options for loading geometry.
unsigned int uint
Definition: SYS_Types.h:45
bool jsonLoadPointReference(GA_Detail &gdp, UT_JSONParser &p, const GA_LoadMap &loadmap) const
bool isStdin() const
Test whether the read handle reads from stdin.
Definition: GA_IO.h:216