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