HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GLTF_ExportRoot.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef __GLTF_EXPORTROOT_h__
27 #define __GLTF_EXPORTROOT_h__
28 
29 #include "GLTFZ_API.h"
30 
31 #include <GLTF/GLTF_Types.h>
32 #include <GLTFZ/GLTF_ImageExport.h>
33 #include <UT/UT_Array.h>
34 #include <UT/UT_ArraySet.h>
35 #include <UT/UT_WorkBuffer.h>
36 
37 #include <GLTF/GLTF_Loader.h>
38 
39 #include <vector>
40 
41 constexpr const char *GENERATOR_STRING = "Houdini GLTF 2.0 Exporter";
42 constexpr const char *GLTF_VERSION = "2.0";
43 
44 class UT_WorkBuffer;
45 class UT_JSONWriter;
46 class UT_OFStream;
47 class OP_Node;
48 
49 namespace GLTF_NAMESPACE
50 {
51 
53 {
54 public:
56  {
57  bool exportNames = false;
58  };
59 
61  {
64  };
65 
67  ~GLTF_ExportRoot();
68 
69  bool HasCachedChannelImage(
70  const UT_Array<GLTF_ChannelMapping> &mapping) const;
72  GetCachedChannelImage(const UT_Array<GLTF_ChannelMapping> &mapping);
73  void
74  InsertCachedChannelImage(const UT_Array<GLTF_ChannelMapping> &mapping,
75  GLTF_Handle idx);
76 
77  UT_Map<UT_StringHolder, GLTF_Handle> &GetImageCache();
78  UT_Map<const OP_Node *, GLTF_Handle> &GetMaterialCache();
79 
80  UT_Map<UT_StringHolder, UT_StringHolder>& GetMorphTargetToChannelMap();
81  UT_Map<UT_StringHolder, exint>& GetMorphTargetChannels();
82  UT_Map<UT_StringHolder, InbetweenIndex>& GetMorphTargetInbetweens();
83  UT_Map<UT_StringHolder, UT_Array<fpreal32>>& GetMorphTargetInbetweenWeights();
84 
85  /// This keeps track of the amount of times a specific filename
86  /// outputted to to avoid name collisions
87  UT_Map<UT_StringHolder, GLTF_Int> &GetNameUsagesMap();
88 
89  ///
90  /// Allocates additional space in the buffer in index bid.
91  /// TODO: stop allocating from reallocing space.
92  ///
93  void *BufferAlloc(GLTF_Handle bid, GLTF_Offset bytes, GLTF_Offset alignment,
95 
96  ///
97  /// Returns a reference to the internal root GLTF object
98  ///
99  GLTF_Loader &loader();
100 
101  ///
102  /// Exports this structure as a GLTF file.
103  ///
104  bool ExportGLTF(const UT_String &path);
105 
106  ///
107  /// Exports the file as GLB on os. If a uri is defined on buffer 0,
108  /// it will be ignored. Otherwise, there are no modifications to the
109  /// outputted JSON.
110  ///
111  bool ExportAsGLB(const UT_String &path);
112  void SerializeJSON(UT_JSONWriter &writer);
113 
114  //
115  // Convenience functions: Will return the index of the created
116  // node in the parameter idx.
117  //
118  GLTF_Accessor &CreateAccessor(GLTF_Handle &idx);
119  GLTF_Animation &CreateAnimation(GLTF_Handle &idx);
120  GLTF_Buffer &CreateBuffer(GLTF_Handle &idx);
121  GLTF_BufferView &CreateBufferview(GLTF_Handle &idx);
122  GLTF_Camera &CreateCamera(GLTF_Handle &idx);
123  GLTF_Node &CreateNode(GLTF_Handle &idx);
124  GLTF_Mesh &CreateMesh(GLTF_Handle &idx);
125  GLTF_Scene &CreateScene(GLTF_Handle &idx);
126  GLTF_Skin &CreateSkin(GLTF_Handle &idx);
127  GLTF_Image &CreateImage(GLTF_Handle &idx);
128  GLTF_Texture &CreateTexture(GLTF_Handle &idx);
129  GLTF_Material &CreateMaterial(GLTF_Handle &idx);
130 
131  // Extension components
132  GLTF_Light &createLight(GLTF_Handle &idx);
133 
134  GLTF_Accessor *getAccessor(GLTF_Handle idx);
135  GLTF_Animation *getAnimation(GLTF_Handle idx);
136  GLTF_Asset *getAsset();
137  GLTF_Buffer *getBuffer(GLTF_Handle idx);
138  GLTF_BufferView *getBufferView(GLTF_Handle idx);
139  GLTF_Camera *getCamera(GLTF_Handle idx);
140  GLTF_Image *getImage(GLTF_Handle idx);
141  GLTF_Material *getMaterial(GLTF_Handle idx);
142  GLTF_Mesh *getMesh(GLTF_Handle idx);
143  GLTF_Node *getNode(GLTF_Handle idx);
144  GLTF_Sampler *getSampler(GLTF_Handle idx);
145  GLTF_Handle getDefaultScene();
146  GLTF_Scene *getScene(GLTF_Handle idx);
147  GLTF_Skin *getSkin(GLTF_Handle idx);
148  GLTF_Texture *getTexture(GLTF_Handle idx);
149 
150  void SetDefaultScene(GLTF_Handle idx);
151 
152  const UT_Array<GLTF_Accessor *> &getAccessors() const;
153  const UT_Array<GLTF_Animation *> &getAnimations() const;
154  const UT_Array<GLTF_Buffer *> &getBuffers() const;
155  const UT_Array<GLTF_BufferView *> &getBufferViews() const;
156  const UT_Array<GLTF_Camera *> &getCameras() const;
157  const UT_Array<GLTF_Extension *> &getExtensions() const;
158  const UT_Array<GLTF_Image *> &getImages() const;
159  const UT_Array<GLTF_Material *> &getMaterials() const;
160  const UT_Array<GLTF_Mesh *> &getMeshes() const;
161  const UT_Array<GLTF_Node *> &getNodes() const;
162  const UT_Array<GLTF_Sampler *> &getSamplers() const;
163  const UT_Array<GLTF_Scene *> &getScenes() const;
164  const UT_Array<GLTF_Skin *> &getSkins() const;
165  const UT_Array<GLTF_Texture *> &getTextures() const;
166 
167  template <typename T>
169  const UT_Array<T>& arr,
171  {
172  T min, max;
173  GLTF_Handle bv_index = createScalarBufferView(arr, min, max);
174 
176  GLTF_Accessor &accessor = CreateAccessor(index);
177  accessor.bufferView = bv_index;
178  accessor.componentType = type;
179  accessor.count = arr.entries();
180  accessor.type = GLTF_TYPE_SCALAR;
181  accessor.min.append(min);
182  accessor.max.append(max);
183 
184  return index;
185  }
186 
187  template <typename T>
189  const UT_Array<UT_Array<T>* >& arr,
191  {
192  T min, max;
193  GLTF_Handle bv_index = createScalarBufferViewInterleaved(arr, min, max);
194 
196  GLTF_Accessor& accessor = CreateAccessor(index);
197  accessor.bufferView = bv_index;
198  accessor.componentType = type;
199  accessor.count = arr.entries() * arr[0]->entries();
200  accessor.type = GLTF_TYPE_SCALAR;
201  accessor.min.append(min);
202  accessor.max.append(max);
203 
204  return index;
205  }
206 
207  template <typename T>
209  const UT_Array<T>& arr,
210  T& min,
211  T& max)
212  {
213  const exint count = arr.entries();
214  GLTF_Offset size = count * sizeof(T);
216  void *buffer = BufferAlloc(0, size, sizeof(T), offset);
217 
218  memcpy(buffer, arr.getRawArray(), size);
219  auto min_max = std::minmax_element(arr.begin(), arr.end());
220 
221  GLTF_Handle bv_index;
222  GLTF_BufferView &bufferview = CreateBufferview(bv_index);
223  bufferview.buffer = 0;
224  bufferview.byteLength = size;
225  bufferview.byteOffset = offset;
226 
227  min = *min_max.first;
228  max = *min_max.second;
229  return bv_index;
230  }
231 
232  template <typename T>
234  const UT_Array<UT_Array<T>* >& arr,
235  T& min,
236  T& max)
237  {
238  const exint count = arr.entries() * arr[0]->entries();
239  GLTF_Offset size = count * sizeof(T);
241  void* buffer = BufferAlloc(0, size, sizeof(T), offset);
242  T* buf_t = static_cast<T*>(buffer);
243 
244  T local_min = (*arr[0])[0];
245  T local_max = (*arr[0])[0];
246 
247  for (exint i = 0; i < arr[0]->entries(); ++i)
248  {
249  for (exint j = 0; j < arr.entries(); ++j)
250  {
251  buf_t[i * arr.entries() + j] = (*arr[j])[i];
252 
253  if ((*arr[j])[i] < local_min)
254  local_min = (*arr[j])[i];
255  if ((*arr[j])[i] > local_max)
256  local_max = (*arr[j])[i];
257  }
258  }
259 
260  GLTF_Handle bv_index;
261  GLTF_BufferView& bufferview = CreateBufferview(bv_index);
262  bufferview.buffer = 0;
263  bufferview.byteLength = size;
264  bufferview.byteOffset = offset;
265 
266  min = local_min;
267  max = local_max;
268  return bv_index;
269  }
270 
271 private:
272  void
273  OutputName(UT_JSONWriter &writer, const char *string, const char *value);
274 
275  void SerializeAsset(UT_JSONWriter &writer);
276  void SerializeAnimations(UT_JSONWriter &writer);
277  void SerializeAccessors(UT_JSONWriter &writer);
278  void SerializeBuffers(UT_JSONWriter &writer);
279  void SerializeBufferViews(UT_JSONWriter &writer);
280  void SerializeCameras(UT_JSONWriter &writer);
281  void SerializeExtensions(UT_JSONWriter &writer);
282  void SerializeNodes(UT_JSONWriter &writer);
283  void SerializeMeshes(UT_JSONWriter &writer);
284  void SerializeMaterials(UT_JSONWriter &writer);
285  void SerializePrimitives(UT_JSONWriter &writer,
286  const UT_Array<GLTF_Primitive> &primitive);
287  void SerializeTextures(UT_JSONWriter &writer);
288  void SerializeImages(UT_JSONWriter &writer);
289  void SerializeScenes(UT_JSONWriter &writer);
290  void SerializeSkins(UT_JSONWriter &writer);
291 
292  bool OutputBuffer(const char *folder, GLTF_Handle buffer) const;
293  void OutputGLBBuffer(UT_OFStream &stream) const;
294 
295  // Pre-output pass: these should be used only before outputting as they
296  // may potentially invalidate handles
297  void ResolveBufferLengths();
298  void RemoveEmptyBuffers();
299 
300  // Any external files must be copied to the output folder as
301  // GLTF is only required to support "http://" and relative URI
302  void ConvertAbsolutePaths(const UT_String &base_path);
303 
304  // Returns true if opened output stream to given path.
305  // Automatically creates directories in path.
306  bool OpenFileStreamAtPath(const UT_String &path, UT_OFStream &os);
307 
308  UT_Array<UT_Array<char>> myBufferData;
309 
310  UT_Map<UT_StringHolder, GLTF_Handle> myNameUsagesMap;
313 
314  UT_Map<UT_StringHolder, UT_StringHolder> myMorphTargetToChannelMap;
315  UT_Map<UT_StringHolder, exint> myMorphTargetChannels;
316  UT_Map<UT_StringHolder, InbetweenIndex> myMorphTargetInbetweens;
317  UT_Map<UT_StringHolder, UT_Array<fpreal32>> myMorphTargetInbetweenWeights;
318 
319  std::map<std::vector<GLTF_ChannelMapping>, GLTF_Handle>
320  myChannelImageMap;
321 
322  GLTF_Loader myLoader;
323  ExportSettings mySettings;
324 };
325 
326 } // namespace GLTF_NAMESPACE
327 
328 #endif
GLuint GLuint stream
Definition: glcorearb.h:1832
const T * getRawArray() const
Definition: UT_Array.h:837
GLTF_Handle addScalarArray(const UT_Array< T > &arr, GLTF_ComponentType type)
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
uint32 GLTF_Handle
Definition: GLTF_Types.h:48
int64 exint
Definition: SYS_Types.h:125
GLdouble s
Definition: glad.h:3009
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
GLuint buffer
Definition: glcorearb.h:660
uint32 GLTF_Offset
Definition: GLTF_Types.h:47
#define GLTF_NAMESPACE
Definition: GLTF_API.h:42
GLintptr offset
Definition: glcorearb.h:665
Definition: core.h:760
GLTF_Handle createScalarBufferView(const UT_Array< T > &arr, T &min, T &max)
iterator begin()
Definition: UT_Array.h:1006
Portable replacement for std::ofstream.
Definition: UT_OFStream.h:26
UT_Array< fpreal64 > max
Definition: GLTF_Types.h:237
exint append()
Definition: UT_Array.h:142
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:648
GLTF_Handle createScalarBufferViewInterleaved(const UT_Array< UT_Array< T > * > &arr, T &min, T &max)
GLint j
Definition: glad.h:2733
GLsizeiptr size
Definition: glcorearb.h:664
GLuint index
Definition: glcorearb.h:786
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLTF_ComponentType componentType
Definition: GLTF_Types.h:230
Definition: core.h:1131
GLTF_Handle addScalarArraysInterleaved(const UT_Array< UT_Array< T > * > &arr, GLTF_ComponentType type)
constexpr const char * GENERATOR_STRING
#define GLTFZ_API
Definition: GLTFZ_API.h:37
constexpr const char * GLTF_VERSION
type
Definition: core.h:1059
GLint GLsizei count
Definition: glcorearb.h:405
iterator end()
End iterator.
Definition: UT_Array.h:1011
Definition: format.h:2459
UT_Array< fpreal64 > min
Definition: GLTF_Types.h:238