HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GLTF_Refiner.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_REFINER_h__
27 #define __GLTF_REFINER_h__
28 
29 #include "GLTFZ_API.h"
30 
31 #include <GA/GA_Types.h>
32 #include <GLTF/GLTF_Types.h>
33 #include <GLTFZ/GLTF_ExportRoot.h>
34 #include <GT/GT_AttributeList.h>
35 #include <GT/GT_DANumeric.h>
36 #include <GT/GT_Refine.h>
37 #include <GT/GT_Types.h>
38 #include <UT/UT_Function.h>
39 #include <UT/UT_IntrusivePtr.h>
40 #include <UT/UT_Options.h>
41 #include <UT/UT_StringMap.h>
42 
43 class GT_PrimPointMesh;
44 class GT_PrimPolygonMesh;
45 class GT_PrimInstance;
46 class GU_Detail;
47 class GT_GEOPrimPacked;
48 
49 namespace GLTF_NAMESPACE
50 {
51 
54 
56  public UT_IntrusiveRefCounter<GLTF_Refiner>
57 {
58 private:
59 
60  const int32 NOT_IN_SUBMESH = -1;
61 
62  struct CachedData
63  {
64  // Each element of these arrays represents a prim in the mesh
65  UT_Array<UT_IntArray> material_faces_map;
66  UT_Array<GT_DataArrayHandle> prim_indirect_mapping;
67  // Maps a submesh index to an attribute map
69 
70  UT_Array<GT_DataArrayHandle> main_id_to_submesh_id_map;
71 
72  GT_DataArrayHandle split_verts;
73  };
74 
75  struct InstanceData
76  {
80  UT_Array<UT_Matrix4D> xforms;
81  GLTF_RefinerHandle refiner;
82  };
83 
84 public:
85  enum class MeshNameSource
86  {
87  NONE,
88  NODE_NAME,
89  ATTRIBUTE
90  };
91 
93  {
94  bool output_custom_attribs = false;
95  bool exporting_skin = false;
96  // Gets a handle to the associated gltf node
97  UT_Function<exint(exint)> boneCapture_index_to_joint = {};
98  bool blendshape = false;
99 
102  };
103 
105  {
108  GT_AttributeListHandle base_shape = nullptr;
109  CachedData* base_shape_cached_data = nullptr;
110  UT_ArrayMap<int, UT_Array<int>>* split_points_map = nullptr;
111  };
112 
114  const UT_StringHolder &obj_material,
116  RefineOptions options,
117  GLTF_BaseErrorManager* error_manager);
118  ~GLTF_Refiner() override = default;
119 
120  void addPrimitive(const GT_PrimitiveHandle &prim) override;
121 
122  // GLTF buffer allocation is currently unprotected
123  bool allowThreading() const override { return false; }
124 
125  ///
126  /// A convenience function. Refines the detail, and adds meshes
127  /// (or potentially submeshes if instancing is used) to the GLTF_Node
128  /// that is passed in.
129  ///
130  static GLTF_RefinerHandle refine(
131  const GU_Detail *src,
132  GLTF_ExportRoot &root,
133  GLTF_Node &node,
134  const UT_StringHolder &obj_material,
136  RefineOptions options,
137  GLTF_BaseErrorManager* error_manager);
138 
139  // Use cached data to refine different frames of the same geometry
140  void setAddingSubsequentFrames(bool use);
141 
142  void setNode(GLTF_Node* node);
143 
144  void animateInstanceXforms(
146  func);
147 
148  void setBlendShapeInfo(BlendShapeInfo info);
149 
150 private:
151  void processPrimPolygon(GT_PrimPolygonMesh *prim, UT_Matrix4D trans,
152  GLTF_Mesh &mesh);
153 
154  bool processInstance(const GT_PrimInstance *instance);
155  void processInstanceFrame(const GT_PrimInstance *instance);
156  void processBlendShape(const GT_PrimInstance* shape);
157 
158  void addBlendShape(const GT_AttributeListHandle& p_list);
159 
160  GLTF_Handle appendMeshIfNotEmpty(GLTF_Mesh &mesh,
161  const GT_Primitive* prim);
162 
163  void
164  addMesh(const GT_PrimPolygonMesh &prim, UT_Matrix4D trans, GLTF_Mesh &mesh);
165 
166  // Creates a GLTF_Primitive based on the given attributes and
167  // indices then returns a reference to it.
168  GLTF_Primitive &addPoints(
169  const GT_AttributeListHandle &attributes,
171  GLTF_Mesh &mesh,
172  exint submesh_idx);
173 
174  void addMorphTarget(
175  const GT_AttributeListHandle &attributes,
176  GLTF_Mesh &mesh,
177  exint prim_index);
178 
179  // Translates a Houdini component type to the 'closest' GLTF
180  // component type
181  GLTF_ComponentType GetComponentTypeFromStorage(GT_Storage storage);
182 
183  struct Attrib_CopyResult
184  {
185  uint32 size;
186  uint32 offset;
187  UT_Array<fpreal64> elem_min;
188  UT_Array<fpreal64> elem_max;
189  uint32 entries;
190  };
191 
192  template <typename T, typename FUNC_CAST>
193  Attrib_CopyResult
194  CopyAttribData(uint32 bid, const T *arr, GT_Size entries,
195  GT_Size old_tuple_size, GT_Size new_tuple_size,
196  UT_Function<void(FUNC_CAST *)> func, uint32 stride);
197 
198  //
199  // Allocates data from the GLTF buffer 'bid' and moves attribute data
200  // to handle, converting type if needed.
201  // If old_tuple_size > new_tuple_size, then the size of the tuple will
202  // be truncated (this is mainly used for UVs).
203  //
204  template <typename T = void>
205  uint32 AddAttrib(const GT_DataArrayHandle &handle,
206  GLTF_ComponentType target_type, GT_Size new_tuple_size,
207  uint32 bid, GLTF_BufferViewTarget buffer_type,
208  UT_Function<void(T *)> func = {}, uint32 stride = 1);
209 
210  bool ExportAttribute(
211  const UT_StringRef &attrib_name,
212  const GT_DataArrayHandle &attrib_data,
213  UT_StringMap<uint32> &attribute_map);
214 
215  uint32 addBlendShapeAttribute(
216  const GT_AttributeListHandle& blend_shape_attribs,
217  const UT_StringHolder& attrib_name,
218  GLTF_Primitive& prim,
219  exint submesh_idx);
220 
221  bool addBoneCaptureAttribs(
222  const GT_DataArrayHandle &attrib_data,
223  UT_StringMap<uint32> &attribute_map);
224 
225  static exint getNumSubMeshes(UT_Array<UT_IntArray>& material_faces_map);
226 
227  GLTF_ExportRoot &myRoot;
228  GLTF_Node *myNode;
229  const UT_StringHolder &myObjectMaterial;
231  const RefineOptions myOptions;
232 
233  CachedData myCachedData;
234  UT_Array<InstanceData> myInstances;
235  bool myAddingSubsequentFrames;
236 
237  GLTF_BaseErrorManager* myErrorManager;
238 
239  GT_AttributeListHandle myPolygonMesh;
240  CachedData* myPolygonMeshCachedData;
241  BlendShapeInfo myBlendShapeInfo;
242  UT_ArrayMap<int, UT_Array<int>> mySplitPointsMap;
243 };
244 
246 {
247 public:
248  static bool
249  Split(const GT_PrimPolygonMesh &polymesh, fpreal64 tol,
250  GT_AttributeListHandle &new_points, GT_DataArrayHandle &new_vertices,
251  UT_ArrayMap<int, UT_Array<int>>& split_points_map,
252  GLTF_BaseErrorManager* error_manager);
253 
254 private:
256  GLTF_BaseErrorManager* error_manager);
257 
258  // Refines detail and prim attributes down to vertex attributes
259  // (which will later be refined into point attributes)
260  GT_AttributeListHandle refineDetailPrims();
261 
262  // Returns true if the points can be merged
263  template <typename T>
264  inline bool compareAttribs(GT_Offset pt_1, GT_Offset pt_2, T *attr_arr,
265  GT_Size tuple_size) const
266  {
267  for (exint idx = 0; idx < tuple_size; idx++)
268  {
269  GT_Offset of1 = pt_1 * tuple_size + idx;
270  GT_Offset of2 = pt_2 * tuple_size + idx;
271  if (SYSabs(attr_arr[of1] - attr_arr[of2]) > myTol)
272  {
273  return true;
274  }
275  }
276 
277  return false;
278  }
279 
280  template <typename T>
281  inline bool compareArrayAttribs(GT_Offset pt_1, GT_Offset pt_2,
282  const UT_Array<T>& vals, const UT_Array<int>& arr_sizes,
283  const UT_Array<GT_Offset>& offset_cache) const
284  {
285  int arr_size1 = arr_sizes[pt_1];
286  int arr_size2 = arr_sizes[pt_2];
287 
288  if (arr_size1 != arr_size2)
289  {
290  return true;
291  }
292 
293  GT_Offset off1 = offset_cache[pt_1];
294  GT_Offset off2 = offset_cache[pt_2];
295 
296  for (exint arr_idx = 0; arr_idx < arr_size1; arr_idx++)
297  {
298  if (SYSabs(vals[off1+arr_idx] - vals[off2+arr_idx]) > myTol)
299  {
300  return true;
301  }
302  }
303 
304  return false;
305  }
306 
307  template <typename T>
309  splitAttribute(GT_Int32Array *new_verts,
310  UT_Array<UT_Array<GT_Offset>> &vertexes_using_point,
311  GT_Int32Array *new_pts_indirect, T *attr_arr,
312  GT_Size tuple_size,
313  UT_ArrayMap<int, UT_Array<int>>& split_points_map);
314 
315  template <typename T>
317  splitAttribute(GT_Int32Array* new_verts,
318  UT_Array<UT_Array<GT_Offset>>& vertexes_using_point,
319  GT_Int32Array* new_pts_indirect,
320  const UT_Array<T>& vals,
321  const UT_Array<int>& arr_sizes,
322  const UT_Array<GT_Offset>& offset_cache,
323  UT_ArrayMap<int, UT_Array<int>>& split_points_map);
324 
325  bool
326  splitAttrib(GT_AttributeListHandle &new_points, GT_DataArrayHandle &new_vertice,
327  const GT_AttributeListHandle &vertex_attribs, exint idx,
328  UT_ArrayMap<int, UT_Array<int>>& split_points_map);
329 
330  const GT_PrimPolygonMesh &myPrim;
331  const fpreal myTol;
332  UT_ArrayMap<int, int> mySourcePointMap;
333  GLTF_BaseErrorManager* myErrorManager;
334 };
335 
336 }
337 
338 #endif
GT_Storage
Definition: GT_Types.h:19
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
int int32
Definition: SYS_Types.h:39
Unsorted map container.
Definition: UT_Map.h:107
A mesh of polygons.
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
uint32 GLTF_Handle
Definition: GLTF_Types.h:48
int64 exint
Definition: SYS_Types.h:125
#define SYSabs(a)
Definition: SYS_Math.h:1540
A reference counter base class for use with UT_IntrusivePtr.
double fpreal64
Definition: SYS_Types.h:201
#define GLTF_NAMESPACE
Definition: GLTF_API.h:42
GLintptr offset
Definition: glcorearb.h:665
GA_API const UT_StringHolder trans
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
int64 GT_Offset
Definition: GT_Types.h:129
A mesh of unconnected points.
bool allowThreading() const override
Return true if the refinement allows threaded refinement of primitives.
Definition: GLTF_Refiner.h:123
GLuint const GLchar * name
Definition: glcorearb.h:786
std::function< T > UT_Function
Definition: UT_Function.h:37
The base class for all GT primitive types.
Definition: GT_Primitive.h:43
#define GLTF_INVALID_IDX
Definition: GLTF_Types.h:44
UT_IntrusivePtr< GLTF_Refiner > GLTF_RefinerHandle
Definition: GLTF_Refiner.h:52
Processes primitives generated by refinement process.
Definition: GT_Refine.h:20
Container for a GU packed primitive.
int64 GT_Size
Definition: GT_Types.h:128
GLsizeiptr size
Definition: glcorearb.h:664
A map of string to various well defined value types.
Definition: UT_Options.h:84
GLenum func
Definition: glcorearb.h:783
fpreal64 fpreal
Definition: SYS_Types.h:277
unsigned int uint32
Definition: SYS_Types.h:40
An array of numeric values (int32, int64, fpreal16, fpreal32, fpreal64)
Definition: GT_DANumeric.h:23
#define GLTFZ_API
Definition: GLTFZ_API.h:37
myRoot
Definition: UT_RTreeImpl.h:716
GLenum src
Definition: glcorearb.h:1793