HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_Copy2.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024
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  * Declarations of functions and structures for copying geometry.
27  */
28 
29 #pragma once
30 
31 #ifndef __HDK_GU_Copy2_h__
32 #define __HDK_GU_Copy2_h__
33 
34 #include <GEO/GEO_PackedTypes.h>
36 #include <GA/GA_OffsetList.h>
37 #include <GA/GA_PolyCounts.h>
38 #include <GA/GA_Types.h>
39 #include <UT/UT_Array.h>
40 #include <UT/UT_ArrayStringMap.h>
41 #include <UT/UT_SmallArray.h>
42 #include <UT/UT_UniquePtr.h>
43 #include <UT/UT_VectorTypes.h>
44 #include <SYS/SYS_StaticAssert.h>
45 #include <SYS/SYS_Types.h>
46 
47 #include <utility> // For std::pair
48 
49 class GA_PointGroup;
50 class GA_PrimitiveGroup;
51 class GA_SplittableRange;
52 class GU_Detail;
54 
55 namespace HDK_Sample {
56 
58 {
65  {
67  {
69  }
70  }
71 
73  {
74  myTransformMatrices3F.reset();
75  myTransformMatrices3D.reset();
78  myTransformInverse3F.reset();
79  myTransformInverse3D.reset();
83  }
84 
85  /// This is for keeping track of whether transforms have changed since the last cook.
91 
101 };
102 
104 {
111  myPrevHadSourceGroup(false),
112  myPrevHadTargetGroup(false),
113  myPrevPack(false),
122  myPrevPivotEnum(PackedPivot::CENTROID),
124  {}
125 
135 
136  enum class PackedPivot
137  {
138  ORIGIN,
139  CENTROID
140  };
141 
142  /// These are only used when myPrevPack is true.
147 
151 
152  /// This is for keeping track of whether source attributes need to be re-copied.
153  /// @{
157  /// @}
158 
160  {
161  COPY,
162  NONE,
163  MULTIPLY,
164  ADD,
165  SUBTRACT
166  };
168  {
172 
177  {}
178  };
180 
181  /// This is for keeping track of whether target attributes need to be re-copied.
182  /// @{
185  /// @}
186 
187  struct PieceData
188  {
189  /// This is the number of target points that reference this piece.
191 
194  "Array above depends on owners other than detail being less than 3");
195 
196  /// This maps from the index into mySourceVertex to the index into mySourcePoints.
198 
201 
203 
206  };
207 
212  "Array above depends on owners other than detail being less than 3");
213 
217 };
218 
219 namespace GU_Copy
220 {
221 
222 void
224  GU_Detail *output_geo,
225  const GU_Detail *source,
226  const GU_Detail *target,
227  GU_CopyToPointsCache *cache,
228  const GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info,
229  const GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info);
230 
231 /// NOTE: transforms_changed must be initialized in advance to the condition
232 /// of whether there are external factors that lead the transforms
233 /// to need to be recomputed, e.g. the target point list changing from
234 /// the previous cook.
235 void
237  GU_PointTransformCache *cache,
238  const GA_OffsetListRef &target_point_list,
239  const GU_Detail *target,
240  const bool transform_using_more_than_P,
241  const bool allow_implicit_N,
242  bool &transforms_changed);
243 
244 namespace NeededTransforms {
245 enum
246 {
248 };
249 }
250 
251 /// Adds to output_geo any missing attributes from source or target as needed.
252 /// Also optionally computes what transform caches are needed for source
253 /// attributes.
254 ///
255 /// If an attribute is in both source and target_attrib_info/target_group_info,
256 /// it will be taken from target if myCombineMethod is COPY, and will be taken
257 /// from source if MULTIPLY, ADD, or SUBTRACT.
258 ///
259 /// If there is only a source, e.g. if output_geo is the internal detail of a
260 /// packed geometry primitive, omit target, target_attrib_info,
261 /// target_group_info, and num_target_attribs.
262 ///
263 /// If there is only a target, pass nullptr for source, and then
264 /// num_source_attribs, has_transform_matrices, and needed_transforms will
265 /// be ignored.
266 ///
267 /// NOTE: num_source_attribs or num_target_attribs, if non-null, should be an
268 /// array long enough to support GA_ATTRIB_VERTEX, GA_ATTRIB_POINT, and
269 /// GA_ATTRIB_PRIMITIVE as indices, (3 at the moment, since they come
270 /// first in GA_AttributeOwner).
271 /// NOTE: needed_transforms, if non-null, should be an array of length
272 /// NeededTransforms::num_needed_transforms.
273 void
275  GU_Detail *output_geo,
276  const GU_Detail *source,
277  exint *num_source_attribs = nullptr,
278  bool has_transform_matrices = false,
279  bool *needed_transforms = nullptr,
280  const GU_Detail *target = nullptr,
281  GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info = nullptr,
282  GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info = nullptr,
283  exint *num_target_attribs = nullptr);
284 
285 void
287  GU_PointTransformCache *cache,
288  exint num_target_points,
289  bool transforms_changed,
290  const bool needed_transforms[NeededTransforms::num_needed_transforms]);
291 
292 /// NOTE: This does not clear output_geo.
293 void
295  GU_Detail *output_geo,
296  const GU_Detail *const source,
297  const GA_OffsetList &source_point_list_cache,
298  const GA_OffsetList &source_vertex_list_cache,
299  const GA_OffsetList &source_prim_list_cache,
300  const exint ncopies);
301 
302 void
304  GA_OffsetList &offset_list,
305  const GU_Detail *const detail,
306  const GA_ElementGroup *const group,
307  const GA_AttributeOwner owner);
308 
309 /// NOTE: This does not clear output_geo.
310 /// NOTE: The point and primitive lists must be created with GUcreatePointOrPrimList.
311 void
313  GU_Detail *output_geo,
314  const GU_Detail *const source,
315  const exint source_point_count,
316  const exint source_vertex_count,
317  const exint source_prim_count,
318  const GA_OffsetList &source_point_list_cache,
319  GA_OffsetList &source_vertex_list_cache,
320  const GA_OffsetList &source_prim_list_cache,
321  const GA_PointGroup *const source_pointgroup,
322  const GA_PrimitiveGroup *const source_primgroup,
323  const exint ncopies);
324 
325 void
327  GU_Detail *const output_geo,
328  const exint num_packed_prims);
329 
330 void
332  GU_Detail *const output_geo,
333  const GA_SplittableRange *const output_splittable_ranges,
334  const GU_Detail *const source,
335  const exint num_target_points,
336  GU_CopyToPointsCache *const cache,
337  const GA_OffsetList *const source_offset_lists,
338  const exint *const num_source_attribs,
339  const bool no_transforms,
340  const bool had_transform_matrices,
341  const bool has_transform_matrices,
342  const bool topology_changed,
343  const bool transforms_changed,
344  const GU_Detail *const target = nullptr,
345  const GU_CopyToPointsCache::TargetAttribInfoMap *const target_attrib_info = nullptr,
346  const GU_CopyToPointsCache::TargetAttribInfoMap *const target_group_info = nullptr,
347  const exint *const target_to_piecei = nullptr,
348  const UT_Array<exint> *const owner_piece_offset_starts = nullptr,
349  const GU_CopyToPointsCache::PieceData *const piece_data = nullptr);
350 
351 void
353  GU_Detail *const output_geo,
354  const GA_SplittableRange *const output_splittable_ranges,
355  const exint ncopies,
356  GU_CopyToPointsCache *const cache,
357  const exint source_point_count,
358  const exint source_vertex_count,
359  const exint source_prim_count,
360  const exint *const num_target_attribs,
361  const GA_OffsetListRef &target_point_list,
362  const GU_Detail *const target,
363  GU_CopyToPointsCache::TargetAttribInfoMap &target_attrib_info,
365  const bool topology_changed,
366  const exint *const target_to_piecei = nullptr,
367  const UT_Array<exint> *const owner_piece_offset_starts = nullptr,
368  const GU_CopyToPointsCache::PieceData *const piece_data = nullptr);
369 
370 /// This sets the packed primitive local transforms,
371 /// and sets P based on the translations and pivots.
372 void
374  GU_Detail *output_geo,
375  GU_CopyToPointsCache *cache,
376  const bool had_transform_matrices,
377  const exint num_packed_prims,
378  const UT_Vector3 *const constant_pivot);
379 
380 /// This sets the packed primitive local transforms,
381 /// sets P based on the translations and pivots,
382 /// (i.e. it first calls GUupdatePackedPrimTransforms),
383 /// then removes unnecessary attributes, adds needed attributes from target,
384 /// and copies target attribute values.
385 ///
386 /// NOTE: constant_pivot being null means to get pivots from the primitives.
387 void
389  GU_Detail *output_geo,
390  GU_CopyToPointsCache *cache,
391  const bool topology_changed,
392  const bool had_transform_matrices,
393  const GU_Detail *const target,
394  const GA_OffsetListRef &target_point_list,
395  GU_CopyToPointsCache::TargetAttribInfoMap &target_attrib_info,
397  const UT_Vector3 *const constant_pivot);
398 
399 /// Uses the transforms in cache and geometry from source
400 /// to create num_packed_prims packed geometry primitives referencing
401 /// the same geometry. If the source groups are null, source_handle
402 /// will be used to create the packed geometry primitives.
403 ///
404 /// If target and the later parameters are non-null, target attributes
405 /// in target_attrib_info and target_group_info will be copied from
406 /// the points in target_point_list.
407 ///
408 /// NOTE: This will clear output_geo if the topology has changed since
409 /// the previous cook.
410 void
412  GU_Detail *output_geo,
413  const GEO_ViewportLOD lod,
414  const GU_CopyToPointsCache::PackedPivot pivot_type,
415  GU_CopyToPointsCache *cache,
416  const GU_ConstDetailHandle source_handle,
417  const GU_Detail *source,
418  const GA_PointGroup *source_pointgroup,
419  const GA_PrimitiveGroup *source_primgroup,
420  bool source_topology_changed,
421  bool had_transform_matrices,
422  bool transforms_changed,
423  const exint num_packed_prims,
424  const GU_Detail *target = nullptr,
425  const GA_OffsetListRef *target_point_list = nullptr,
426  GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info = nullptr,
427  GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info = nullptr);
428 
429 
430 } // namespace GU_Copy
431 
432 } // End of HDK_Sample namespace
433 
434 namespace UT {
435 template <typename T>
436 struct DefaultClearer;
437 
438 template<>
440 {
443  {
447  }
450  {
451  return
453  v.myCopyTo == GA_ATTRIB_POINT &&
455  }
458  {
460  }
461  static const bool clearNeedsDestruction = false;
462 };
463 }
464 
465 namespace UT {
466 template <typename T>
467 struct DefaultClearer;
468 
469 // FIXME: Move this specialization to GA_OffsetList.h and template it for all GA_ListType and GA_ListTypeRef!
470 template<>
471 struct DefaultClearer<GA_OffsetList>
472 {
474  static void clear(GA_OffsetList &v)
475  {
476  v.clear();
477  }
479  static bool isClear(const GA_OffsetList &v)
480  {
481  return v.size() == 0 && v.isTrivial() && v.trivialStart() == GA_Offset(0) && !v.getExtraFlag();
482  }
484  static void clearConstruct(GA_OffsetList *p)
485  {
486  new ((void *)p) GA_OffsetList();
487  }
488  static const bool clearNeedsDestruction = false;
489 };
490 }
491 
492 #endif
void GUcopyPackAllSame(GU_Detail *output_geo, const GEO_ViewportLOD lod, const GU_CopyToPointsCache::PackedPivot pivot_type, GU_CopyToPointsCache *cache, const GU_ConstDetailHandle source_handle, const GU_Detail *source, const GA_PointGroup *source_pointgroup, const GA_PrimitiveGroup *source_primgroup, bool source_topology_changed, bool had_transform_matrices, bool transforms_changed, const exint num_packed_prims, const GU_Detail *target, const GA_OffsetListRef *target_point_list, GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info)
Definition: GU_Copy2.C:3401
SYS_FORCE_INLINE void clear()
clear removes all of the entries
void GUcreatePointOrPrimList(GA_OffsetList &offset_list, const GU_Detail *const detail, const GA_ElementGroup *const group, const GA_AttributeOwner owner)
Definition: GU_Copy2.C:1897
void GUcopyAttributesFromSource(GU_Detail *const output_geo, const GA_SplittableRange *const output_splittable_ranges, const GU_Detail *const source, const exint num_target_points, GU_CopyToPointsCache *const cache, const GA_OffsetList *const source_offset_lists, const exint *const num_source_attribs, const bool no_transforms, const bool had_transform_matrices, const bool has_transform_matrices, const bool topology_changed, const bool transforms_changed, const GU_Detail *const target, const GU_CopyToPointsCache::TargetAttribInfoMap *const target_attrib_info, const GU_CopyToPointsCache::TargetAttribInfoMap *const target_group_info, const exint *const target_to_piecei, const UT_Array< exint > *const owner_piece_offset_starts, const GU_CopyToPointsCache::PieceData *const piece_data)
Definition: GU_Copy2.C:2012
UT_UniquePtr< UT_Vector3D[]> myTransformTranslates3D
Definition: GU_Copy2.h:95
void GUupdatePackedPrimTransforms(GU_Detail *output_geo, GU_CopyToPointsCache *cache, const bool had_transform_matrices, const exint num_packed_prims, const UT_Vector3 *const constant_pivot)
Definition: GU_Copy2.C:3203
UT_ArrayStringMap< GA_DataId > mySourceGroupDataIDs[3]
Definition: GU_Copy2.h:155
GA_OffsetList myTargetOffsetList
Definition: GU_Copy2.h:150
int64 GA_DataId
Definition: GA_Types.h:687
const GLdouble * v
Definition: glcorearb.h:837
GA_OffsetListType< GA_Size > GA_OffsetList
GA_OffsetList is a map from index to offset.
void GUcreateVertexListAndGeometryFromSource(GU_Detail *output_geo, const GU_Detail *const source, const exint source_point_count, const exint source_vertex_count, const exint source_prim_count, const GA_OffsetList &source_point_list_cache, GA_OffsetList &source_vertex_list_cache, const GA_OffsetList &source_prim_list_cache, const GA_PointGroup *const source_pointgroup, const GA_PrimitiveGroup *const source_primgroup, const exint ncopies)
Definition: GU_Copy2.C:1921
SYS_FORCE_INLINE bool getExtraFlag() const
Synonym for isClosed()
int64 exint
Definition: SYS_Types.h:125
void GUcomputeTransformTypeCaches(GU_PointTransformCache *cache, exint num_target_points, bool transforms_changed, const bool needed_transforms[NeededTransforms::num_needed_transforms])
Definition: GU_Copy2.C:738
void GUcreateGeometryFromSource(GU_Detail *output_geo, const GU_Detail *const source, const GA_OffsetList &source_point_list_cache, const GA_OffsetList &source_vertex_list_cache, const GA_OffsetList &source_prim_list_cache, const exint ncopies)
NOTE: This does not clear output_geo.
Definition: GU_Copy2.C:1689
void GUcopyAttributesFromTarget(GU_Detail *const output_geo, const GA_SplittableRange *const output_splittable_ranges, const exint ncopies, GU_CopyToPointsCache *const cache, const exint source_point_count, const exint source_vertex_count, const exint source_prim_count, const exint *const num_target_attribs, const GA_OffsetListRef &target_point_list, const GU_Detail *const target, GU_CopyToPointsCache::TargetAttribInfoMap &target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap &target_group_info, const bool topology_changed, const exint *const target_to_piecei, const UT_Array< exint > *const owner_piece_offset_starts, const GU_CopyToPointsCache::PieceData *const piece_data)
Definition: GU_Copy2.C:2699
#define GA_INVALID_DATAID
Definition: GA_Types.h:688
static SYS_FORCE_INLINE void clear(GA_OffsetList &v)
Definition: GU_Copy2.h:474
GA_DataId myTargetTransformDataIDs[GA_AttributeInstanceMatrix::theNumAttribs]
This is for keeping track of whether transforms have changed since the last cook. ...
Definition: GU_Copy2.h:86
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
UT_UniquePtr< UT_Matrix3D[]> myTransformMatrices3D
Definition: GU_Copy2.h:93
GA_Size GA_Offset
Definition: GA_Types.h:641
SYS_FORCE_INLINE bool isTrivial() const
UT_UniquePtr< UT_Vector3F[]> myTransformTranslates3F
Definition: GU_Copy2.h:94
static SYS_FORCE_INLINE bool isClear(const HDK_Sample::GU_CopyToPointsCache::TargetAttribInfo &v)
Definition: GU_Copy2.h:449
GEO_ViewportLOD myPrevViewportLOD
Definition: GU_Copy2.h:146
void GUcreateEmptyPackedGeometryPrims(GU_Detail *const output_geo, const exint num_packed_prims)
Definition: GU_Copy2.C:1978
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
void GUsetupPointTransforms(GU_PointTransformCache *cache, const GA_OffsetListRef &target_point_list, const GU_Detail *target, const bool transform_using_more_than_P, const bool allow_implicit_N, bool &transforms_changed)
Definition: GU_Copy2.C:304
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
UT_SmallArray< std::pair< int, exint >, sizeof(std::pair< int, exint >)> myPrimTypeCountPairs
Definition: GU_Copy2.h:204
UT_Array< PieceData > myPieceData
Definition: GU_Copy2.h:208
UT_ArrayStringMap< GA_DataId > mySourceAttribDataIDs[3]
Definition: GU_Copy2.h:154
GLenum target
Definition: glcorearb.h:1667
GA_OffsetList mySourceOffsetLists[3]
Definition: GU_Copy2.h:149
UT_SmallArray< exint, 2 *sizeof(exint)> myClosedSpanLengths
Definition: GU_Copy2.h:205
void GUhandleTargetAttribsForPackedPrims(GU_Detail *output_geo, GU_CopyToPointsCache *cache, const bool topology_changed, const bool had_transform_matrices, const GU_Detail *const target, const GA_OffsetListRef &target_point_list, GU_CopyToPointsCache::TargetAttribInfoMap &target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap &target_group_info, const UT_Vector3 *const constant_pivot)
Definition: GU_Copy2.C:3331
GA_AttributeOwner
Definition: GA_Types.h:34
void GUaddAttributesFromSourceOrTarget(GU_Detail *output_geo, const GU_Detail *source, exint *num_source_attribs, bool has_transform_matrices, bool *needed_transforms, const GU_Detail *target, GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info, GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info, exint *num_target_attribs)
Definition: GU_Copy2.C:457
UT_UniquePtr< UT_Matrix3F[]> myTransformInverse3F
Definition: GU_Copy2.h:96
UT_Array< exint > myPieceOffsetStarts[3]
Definition: GU_Copy2.h:210
UT_UniquePtr< UT_QuaternionD[]> myTransformQuaternionsD
Definition: GU_Copy2.h:99
UT_Array< exint > myTargetToPiece
Definition: GU_Copy2.h:209
void GUremoveUnnecessaryAttribs(GU_Detail *output_geo, const GU_Detail *source, const GU_Detail *target, GU_CopyToPointsCache *cache, const GU_CopyToPointsCache::TargetAttribInfoMap *target_attrib_info, const GU_CopyToPointsCache::TargetAttribInfoMap *target_group_info)
Definition: GU_Copy2.C:137
GEO_ViewportLOD
SYS_STATIC_ASSERT_MSG(int(GA_ATTRIB_VERTEX)< 3 &&int(GA_ATTRIB_POINT)< 3 &&int(GA_ATTRIB_PRIMITIVE)< 3,"Array above depends on owners other than detail being less than 3")
static SYS_FORCE_INLINE void clearConstruct(HDK_Sample::GU_CopyToPointsCache::TargetAttribInfo *p)
Definition: GU_Copy2.h:457
static SYS_FORCE_INLINE bool isClear(const GA_OffsetList &v)
Definition: GU_Copy2.h:479
UT_ArrayStringMap< GA_DataId > mySourceEdgeGroupDataIDs
Definition: GU_Copy2.h:156
SYS_STATIC_ASSERT_MSG(int(GA_ATTRIB_VERTEX)< 3 &&int(GA_ATTRIB_POINT)< 3 &&int(GA_ATTRIB_PRIMITIVE)< 3,"Array above depends on owners other than detail being less than 3")
exint myRefCount
This is the number of target points that reference this piece.
Definition: GU_Copy2.h:190
SYS_FORCE_INLINE ToType trivialStart() const
Returns the start, assuming this list is trivial.
TargetAttribInfoMap myTargetGroupInfo
Definition: GU_Copy2.h:184
GA_ListType< exint, exint > myRelVtxToPt
This maps from the index into mySourceVertex to the index into mySourcePoints.
Definition: GU_Copy2.h:197
exint myPrevSourceUniqueID
These are only used when myPrevPack is true.
Definition: GU_Copy2.h:143
UT_UniquePtr< UT_QuaternionF[]> myTransformQuaternionsF
Definition: GU_Copy2.h:98
GLint lod
Definition: glcorearb.h:2765
UT_UniquePtr< UT_Matrix3D[]> myTransformInverse3D
Definition: GU_Copy2.h:97
UT_UniquePtr< UT_Matrix3F[]> myTransformMatrices3F
Definition: GU_Copy2.h:92
TargetAttribInfoMap myTargetAttribInfo
Definition: GU_Copy2.h:183
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
static SYS_FORCE_INLINE void clear(HDK_Sample::GU_CopyToPointsCache::TargetAttribInfo &v)
Definition: GU_Copy2.h:442
static SYS_FORCE_INLINE void clearConstruct(GA_OffsetList *p)
Definition: GU_Copy2.h:484