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  {
79  UT_Array<UT_Matrix4D> xforms;
80  GLTF_RefinerHandle refiner;
81  };
82 
83 public:
85  {
86  bool output_custom_attribs = false;
88  bool exporting_skin = false;
89  // Gets a handle to the associated gltf node
90  std::function<exint(exint)> boneCapture_index_to_joint = {};
91  bool blendshape = false;
92  };
93 
95  {
98  GT_AttributeListHandle base_shape = nullptr;
99  CachedData* base_shape_cached_data = nullptr;
100  UT_ArrayMap<int, UT_Array<int>>* split_points_map = nullptr;
101  };
102 
104  const UT_StringHolder &obj_material,
105  std::function<GLTF_Handle(UT_StringHolder, UT_Options&)> create_material,
106  Refine_Options options,
107  GLTF_BaseErrorManager* error_manager);
108  ~GLTF_Refiner() override = default;
109 
110  void addPrimitive(const GT_PrimitiveHandle &prim) override;
111 
112  // GLTF buffer allocation is currently unprotected
113  bool allowThreading() const override { return false; }
114 
115  ///
116  /// A convenience function. Refines the detail, and adds meshes
117  /// (or potentially submeshes if instancing is used) to the GLTF_Node
118  /// that is passed in.
119  ///
120  static GLTF_RefinerHandle refine(
121  const GU_Detail *src,
122  GLTF_ExportRoot &root,
123  GLTF_Node &node,
124  const UT_StringHolder &obj_material,
125  std::function<GLTF_Handle(UT_StringHolder, UT_Options&)> create_material,
126  Refine_Options options,
127  GLTF_BaseErrorManager* error_manager);
128 
129  // Use cached data to refine different frames of the same geometry
130  void setAddingSubsequentFrames(bool use);
131 
132  void setNode(GLTF_Node* node);
133 
134  void animateInstanceXforms(
135  std::function<void(GLTF_Handle, const UT_Array<UT_Matrix4D> &)>
136  func);
137 
138  void setBlendShapeInfo(BlendShapeInfo info);
139 
140 private:
141  void processPrimPolygon(GT_PrimPolygonMesh *prim, UT_Matrix4D trans,
142  GLTF_Mesh &mesh);
143 
144  bool processInstance(const GT_PrimInstance *instance);
145  void processInstanceFrame(const GT_PrimInstance *instance);
146  void processBlendShape(const GT_PrimInstance* shape);
147 
148  void addBlendShape(const GT_PrimPointMesh* mesh);
149 
150  GLTF_Handle appendMeshIfNotEmpty(GLTF_Mesh &mesh);
151 
152  void
153  addMesh(const GT_PrimPolygonMesh &prim, UT_Matrix4D trans, GLTF_Mesh &mesh);
154 
155  // Creates a GLTF_Primitive based on the given attributes and
156  // indices then returns a reference to it.
157  GLTF_Primitive &addPoints(
158  const GT_AttributeListHandle &attributes,
160  GLTF_Mesh &mesh,
161  exint submesh_idx);
162 
163  void addMorphTarget(
164  const GT_AttributeListHandle &attributes,
165  GLTF_Mesh &mesh,
166  exint prim_index);
167 
168  // Translates a Houdini component type to the 'closest' GLTF
169  // component type
170  GLTF_ComponentType GetComponentTypeFromStorage(GT_Storage storage);
171 
172  struct Attrib_CopyResult
173  {
174  uint32 size;
175  uint32 offset;
176  UT_Array<fpreal64> elem_min;
177  UT_Array<fpreal64> elem_max;
178  uint32 entries;
179  };
180 
181  template <typename T, typename FUNC_CAST>
182  Attrib_CopyResult
183  CopyAttribData(uint32 bid, const T *arr, GT_Size entries,
184  GT_Size old_tuple_size, GT_Size new_tuple_size,
185  std::function<void(FUNC_CAST *)> func, uint32 stride);
186 
187  //
188  // Allocates data from the GLTF buffer 'bid' and moves attribute data
189  // to handle, converting type if needed.
190  // If old_tuple_size > new_tuple_size, then the size of the tuple will
191  // be truncated (this is mainly used for UVs).
192  //
193  template <typename T = void>
194  uint32 AddAttrib(const GT_DataArrayHandle &handle,
195  GLTF_ComponentType target_type, GT_Size new_tuple_size,
196  uint32 bid, GLTF_BufferViewTarget buffer_type,
197  std::function<void(T *)> func = {}, uint32 stride = 1);
198 
199  bool ExportAttribute(
200  const UT_StringRef &attrib_name,
201  const GT_DataArrayHandle &attrib_data,
202  UT_StringMap<uint32> &attribute_map);
203 
204  uint32 addBlendShapeAttribute(const GT_PrimPointMesh* blend_shape,
205  const UT_StringHolder& attrib_name,
206  GLTF_Primitive& prim,
207  exint submesh_idx);
208 
209  bool addBoneCaptureAttribs(
210  const GT_DataArrayHandle &attrib_data,
211  UT_StringMap<uint32> &attribute_map);
212 
213  static exint getNumSubMeshes(UT_Array<UT_IntArray>& material_faces_map);
214 
215  GLTF_ExportRoot &myRoot;
216  GLTF_Node *myNode;
217  const UT_StringHolder &myObjectMaterial;
218  std::function<GLTF_Handle(UT_StringHolder, UT_Options &)> myCreateMaterial;
219  const Refine_Options myOptions;
220 
221  CachedData myCachedData;
222  UT_Array<InstanceData> myInstances;
223  bool myAddingSubsequentFrames;
224 
225  GLTF_BaseErrorManager* myErrorManager;
226 
227  GT_AttributeListHandle myPolygonMesh;
228  CachedData* myPolygonMeshCachedData;
229  BlendShapeInfo myBlendShapeInfo;
230  UT_ArrayMap<int, UT_Array<int>> mySplitPointsMap;
231 };
232 
234 {
235 public:
236  static bool
237  Split(const GT_PrimPolygonMesh &polymesh, fpreal64 tol,
238  GT_AttributeListHandle &new_points, GT_DataArrayHandle &new_vertices,
239  UT_ArrayMap<int, UT_Array<int>>& split_points_map,
240  GLTF_BaseErrorManager* error_manager);
241 
242 private:
244  GLTF_BaseErrorManager* error_manager);
245 
246  // Refines detail and prim attributes down to vertex attributes
247  // (which will later be refined into point attributes)
248  GT_AttributeListHandle refineDetailPrims();
249 
250  // Returns true if the points can be merged
251  template <typename T>
252  inline bool compareAttribs(GT_Offset pt_1, GT_Offset pt_2, T *attr_arr,
253  GT_Size tuple_size) const
254  {
255  for (exint idx = 0; idx < tuple_size; idx++)
256  {
257  GT_Offset of1 = pt_1 * tuple_size + idx;
258  GT_Offset of2 = pt_2 * tuple_size + idx;
259  if (SYSabs(attr_arr[of1] - attr_arr[of2]) > myTol)
260  {
261  return true;
262  }
263  }
264 
265  return false;
266  }
267 
268  template <typename T>
269  inline bool compareArrayAttribs(GT_Offset pt_1, GT_Offset pt_2,
270  const UT_Array<T>& vals, const UT_Array<int>& arr_sizes,
271  const UT_Array<GT_Offset>& offset_cache) const
272  {
273  int arr_size1 = arr_sizes[pt_1];
274  int arr_size2 = arr_sizes[pt_2];
275 
276  if (arr_size1 != arr_size2)
277  {
278  return true;
279  }
280 
281  GT_Offset off1 = offset_cache[pt_1];
282  GT_Offset off2 = offset_cache[pt_2];
283 
284  for (exint arr_idx = 0; arr_idx < arr_size1; arr_idx++)
285  {
286  if (SYSabs(vals[off1+arr_idx] - vals[off2+arr_idx]) > myTol)
287  {
288  return true;
289  }
290  }
291 
292  return false;
293  }
294 
295  template <typename T>
297  splitAttribute(GT_Int32Array *new_verts,
298  UT_Array<UT_Array<GT_Offset>> &vertexes_using_point,
299  GT_Int32Array *new_pts_indirect, T *attr_arr,
300  GT_Size tuple_size,
301  UT_ArrayMap<int, UT_Array<int>>& split_points_map);
302 
303  template <typename T>
305  splitAttribute(GT_Int32Array* new_verts,
306  UT_Array<UT_Array<GT_Offset>>& vertexes_using_point,
307  GT_Int32Array* new_pts_indirect,
308  const UT_Array<T>& vals,
309  const UT_Array<int>& arr_sizes,
310  const UT_Array<GT_Offset>& offset_cache,
311  UT_ArrayMap<int, UT_Array<int>>& split_points_map);
312 
313  bool
314  splitAttrib(GT_AttributeListHandle &new_points, GT_DataArrayHandle &new_vertice,
315  const GT_AttributeListHandle &vertex_attribs, exint idx,
316  UT_ArrayMap<int, UT_Array<int>>& split_points_map);
317 
318  const GT_PrimPolygonMesh &myPrim;
319  const fpreal myTol;
320  UT_ArrayMap<int, int> mySourcePointMap;
321  GLTF_BaseErrorManager* myErrorManager;
322 };
323 
324 }
325 
326 #endif
GT_Storage
Definition: GT_Types.h:18
int int32
Definition: SYS_Types.h:39
Unsorted map container.
Definition: UT_Map.h:83
A mesh of polygons.
uint32 GLTF_Handle
Definition: GLTF_Types.h:48
int64 exint
Definition: SYS_Types.h:125
#define SYSabs(a)
Definition: SYS_Math.h:1537
GLenum src
Definition: glcorearb.h:1792
A reference counter base class for use with UT_IntrusivePtr.
GLsizeiptr size
Definition: glcorearb.h:663
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:405
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:113
#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:782
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:664
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:871
#define GLTFZ_API
Definition: GLTFZ_API.h:37