HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GU_VDBPointTools.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2014 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 //
31 /// @file GU_VDBPointTools.h
32 /// @author FX R&D OpenVDB team
33 ///
34 /// @brief Collection of PointIndexGrid helpers for Houdini
35 
36 #ifndef __GU_VDBPOINTTOOLS_H_HAS_BEEN_INCLUDED__
37 #define __GU_VDBPOINTTOOLS_H_HAS_BEEN_INCLUDED__
38 
39 #if 1
40  #include "GU_Detail.h"
41 #else
42  #include <GU/GU_Detail.h>
43 #endif
44 #include <GA/GA_ElementGroup.h>
45 #include <UT/UT_VectorTypes.h>
46 
47 #include <UT/UT_Version.h>
48 
49 #if (UT_MAJOR_VERSION_INT >= 15)
50  #include "GU_PackedContext.h"
51 #endif
52 
53 #if (UT_MAJOR_VERSION_INT >= 14)
54  #include "GU_PrimPacked.h"
55  #include "GU_PackedGeometry.h"
56  #include "GU_PackedFragment.h"
57  #include "GU_DetailHandle.h"
58 #endif
59 
60 #include <openvdb/Platform.h>
64 
65 
66 /// @brief Houdini point attribute wrapper
67 template <typename VectorType>
69 {
70  typedef hboost::shared_ptr<GU_VDBPointList> Ptr;
71  typedef hboost::shared_ptr<const GU_VDBPointList> ConstPtr;
72 
73  typedef VectorType PosType;
74  typedef typename PosType::value_type ScalarType;
75 
76  GU_VDBPointList(const GU_Detail& detail, const GA_PointGroup* group = NULL)
77  : mPositionHandle(detail.getP())
78  , mVelocityHandle()
79  , mRadiusHandle()
80  , mIndexMap(&detail.getP()->getIndexMap())
81  , mOffsets()
82  , mSize(mIndexMap->indexSize())
83  {
84  if (group) {
85  mSize = group->entries();
86  mOffsets.reserve(mSize);
87 
89  GA_Range range(*group);
90  for (GA_Iterator it = range.begin(); it.blockAdvance(start, end); ) {
91  for (GA_Offset off = start; off < end; ++off) {
92  mOffsets.push_back(off);
93  }
94  }
95 
96  getOffset = &GU_VDBPointList::offsetFromGroupMap;
97  } else if (mIndexMap->isTrivialMap()) {
98  getOffset = &GU_VDBPointList::offsetFromIndexCast;
99  } else {
100  getOffset = &GU_VDBPointList::offsetFromGeoMap;
101  }
102 
103  // Bind optional attributes
104 
106  if (velRef.isValid()) {
107  mVelocityHandle.bind(velRef.getAttribute());
108  }
109 
111  if (radRef.isValid()) {
112  mRadiusHandle.bind(radRef.getAttribute());
113  }
114  }
115 
116  static Ptr create(const GU_Detail& detail, const GA_PointGroup* group = NULL)
117  {
118  return Ptr(new GU_VDBPointList(detail, group));
119  }
120 
121  size_t size() const { return mSize; }
122 
123  bool hasVelocity() const { return mVelocityHandle.isValid(); }
124  bool hasRadius() const { return mRadiusHandle.isValid(); }
125 
126  // Index access methods
127 
128  void getPos(size_t n, PosType& xyz) const {
129  getPosFromOffset((this->*getOffset)(n), xyz);
130  }
131 
132  void getVelocity(size_t n, PosType& v) const {
133  getVelocityFromOffset((this->*getOffset)(n), v);
134  }
135 
136  void getRadius(size_t n, ScalarType& r) const {
137  getRadiusFromOffset((this->*getOffset)(n), r);
138  }
139 
140  // Offset access methods
141 
142  GA_Offset offsetFromIndex(size_t n) const {
143  return (this->*getOffset)(n);
144  }
145 
146  void getPosFromOffset(const GA_Offset offset, PosType& xyz) const {
147  const UT_Vector3 data = mPositionHandle.get(offset);
148  xyz[0] = ScalarType(data[0]);
149  xyz[1] = ScalarType(data[1]);
150  xyz[2] = ScalarType(data[2]);
151  }
152 
154  const UT_Vector3 data = mVelocityHandle.get(offset);
155  v[0] = ScalarType(data[0]);
156  v[1] = ScalarType(data[1]);
157  v[2] = ScalarType(data[2]);
158  }
159 
161  r = ScalarType(mRadiusHandle.get(offset));
162  }
163 
164 private:
165  // Disallow copying
167  GU_VDBPointList& operator=(const GU_VDBPointList&);
168 
169  GA_Offset (GU_VDBPointList::* getOffset)(const size_t) const;
170 
171  GA_Offset offsetFromGeoMap(const size_t n) const {
172  return mIndexMap->offsetFromIndex(GA_Index(n));
173  }
174 
175  GA_Offset offsetFromGroupMap(const size_t n) const {
176  return mOffsets[n];
177  }
178 
179  GA_Offset offsetFromIndexCast(const size_t n) const {
180  return GA_Offset(n);
181  }
182 
183  GA_ROHandleV3 mPositionHandle, mVelocityHandle;
184  GA_ROHandleF mRadiusHandle;
185  GA_IndexMap const * const mIndexMap;
186  std::vector<GA_Offset> mOffsets;
187  size_t mSize;
188 }; // GU_VDBPointList
189 
190 
191 ////////////////////////////////////////
192 
193 
194 // PointIndexGrid utility methods
195 
196 
197 namespace GU_VDBPointToolsInternal {
198 
199 template<typename PointArrayType>
201  IndexToOffsetOp(const PointArrayType& points): mPointList(&points) {}
202 
203  template <typename LeafT>
204  void operator()(LeafT &leaf, size_t /*leafIndex*/) const {
205  typename LeafT::IndexArray& indices = leaf.indices();
206  for (size_t n = 0, N = indices.size(); n < N; ++n) {
207  indices[n] = static_cast<typename LeafT::ValueType::IntType>(
208  mPointList->offsetFromIndex(GA_Index{indices[n]}));
209  }
210  }
211  PointArrayType const * const mPointList;
212 };
213 
214 #if (UT_MAJOR_VERSION_INT >= 14)
215 
216 struct PackedMaskConstructor
217 {
218  PackedMaskConstructor(const std::vector<const GA_Primitive*>& prims,
219  const openvdb::math::Transform& xform)
220  : mPrims(prims.empty() ? NULL : &prims.front())
221  , mXForm(xform)
222  , mMaskGrid(new openvdb::MaskGrid(false))
223  {
224  mMaskGrid->setTransform(mXForm.copy());
225  }
226 
227  PackedMaskConstructor(PackedMaskConstructor& rhs, tbb::split)
228  : mPrims(rhs.mPrims)
229  , mXForm(rhs.mXForm)
230  , mMaskGrid(new openvdb::MaskGrid(false))
231  {
232  mMaskGrid->setTransform(mXForm.copy());
233  }
234 
235  openvdb::MaskGrid::Ptr getMaskGrid() { return mMaskGrid; }
236 
237  void join(PackedMaskConstructor& rhs) { mMaskGrid->tree().topologyUnion(rhs.mMaskGrid->tree()); }
238 
239  void operator()(const tbb::blocked_range<size_t>& range)
240  {
241 
242 #if (UT_MAJOR_VERSION_INT >= 15)
243  GU_PackedContext packedcontext;
244 #endif
245 
246  for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
247  const GA_Primitive *prim = mPrims[n];
248  if (!prim || !GU_PrimPacked::isPackedPrimitive(*prim)) continue;
249 
250  const GU_PrimPacked * pprim = static_cast<const GU_PrimPacked*>(prim);
251 
252  GU_Detail tmpdetail;
253  const GU_Detail *detailtouse;
254 
255 #if (UT_MAJOR_VERSION_INT >= 15)
256 
257  GU_DetailHandleAutoReadLock readlock(pprim->getPackedDetail(packedcontext));
258 
259  UT_Matrix4D mat;
260  pprim->getFullTransform4(mat);
261  if (mat.isIdentity() && readlock.isValid() && readlock.getGdp()) {
262  detailtouse = readlock.getGdp();
263  } else {
264  pprim->unpackWithContext(tmpdetail, packedcontext);
265  detailtouse = &tmpdetail;
266  }
267 #else
268  pprim->unpack(tmpdetail);
269  detailtouse = &tmpdetail;
270 #endif
271 
272  GU_VDBPointList<openvdb::Vec3R> points(*detailtouse);
273  openvdb::MaskGrid::Ptr grid = openvdb::tools::createPointMask(points, mXForm);
274  mMaskGrid->tree().topologyUnion(grid->tree());
275  }
276  }
277 
278 private:
279  GA_Primitive const * const * const mPrims;
280  openvdb::math::Transform mXForm;
281  openvdb::MaskGrid::Ptr mMaskGrid;
282 }; // struct PackedMaskConstructor
283 
284 
285 inline void
286 getPackedPrimitiveOffsets(const GU_Detail& detail, std::vector<const GA_Primitive*>& primitives)
287 {
288  const GA_Size numPacked = GU_PrimPacked::countPackedPrimitives(detail);
289 
290  primitives.clear();
291  primitives.reserve(size_t(numPacked));
292 
293  if (numPacked != GA_Size(0)) {
295  GA_Range range = detail.getPrimitiveRange();
296  const GA_PrimitiveList& primList = detail.getPrimitiveList();
297 
298  for (GA_Iterator it = range.begin(); it.blockAdvance(start, end); ) {
299  for (GA_Offset off = start; off < end; ++off) {
300 
301  const GA_Primitive *prim = primList.get(off);
302 
303  if (prim && GU_PrimPacked::isPackedPrimitive(*prim)) {
304  primitives.push_back(prim);
305  }
306  }
307  }
308  }
309 }
310 
311 #endif
312 
313 
314 } // namespace GU_VDBPointToolsInternal
315 
316 
317 ////////////////////////////////////////
318 
319 
320 /// @brief Utility method to construct a GU_VDBPointList.
321 /// @details The GU_VDBPointList is compatible with the PointIndexGrid and ParticleAtals structures.
323 GUvdbCreatePointList(const GU_Detail& detail, const GA_PointGroup* pointGroup = NULL)
324 {
325  return GU_VDBPointList<openvdb::Vec3s>::create(detail, pointGroup);
326 }
327 
328 
329 /// @brief Utility method to change point indices into Houdini geometry offsets.
330 /// @note PointIndexGrid's that store Houdini geometry offsets are not
331 /// safe to write to disk, offsets are not guaranteed to be immutable
332 /// under defragmentation operations or I/O.
333 template<typename PointIndexTreeType, typename PointArrayType>
334 inline void
335 GUvdbConvertIndexToOffset(PointIndexTreeType& tree, const PointArrayType& points)
336 {
337  openvdb::tree::LeafManager<PointIndexTreeType> leafnodes(tree);
339 }
340 
341 
342 /// @brief Utility method to construct a PointIndexGrid.
343 /// @details The PointIndexGrid supports fast spatial queries for points.
344 inline openvdb::tools::PointIndexGrid::Ptr
346  const openvdb::math::Transform& xform,
347  const GU_Detail& detail,
348  const GA_PointGroup* pointGroup = NULL)
349 {
350  GU_VDBPointList<openvdb::Vec3s> points(detail, pointGroup);
351  return openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(points, xform);
352 }
353 
354 
355 /// @brief Utility method to construct a PointIndexGrid.
356 /// @details The PointIndexGrid supports fast spatial queries for points.
357 template<typename PointArrayType>
358 inline openvdb::tools::PointIndexGrid::Ptr
359 GUvdbCreatePointIndexGrid(const openvdb::math::Transform& xform, const PointArrayType& points)
360 {
361  return openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(points, xform);
362 }
363 
364 
365 /// @brief Utility method to construct a ParticleAtals.
366 /// @details The ParticleAtals supports fast spatial queries for particles.
367 template<typename ParticleArrayType>
368 inline openvdb::tools::ParticleIndexAtlas::Ptr
369 GUvdbCreateParticleAtlas(const double minVoxelSize, const ParticleArrayType& particles)
370 {
372  ParticleIndexAtlas::Ptr atlas(new ParticleIndexAtlas());
373 
374  if (particles.hasRadius()) {
375  atlas->construct(particles, minVoxelSize);
376  }
377 
378  return atlas;
379 }
380 
381 
382 /// @brief Utility method to construct a boolean PointMaskGrid
383 /// @details This method supports packed points.
384 inline openvdb::MaskGrid::Ptr
386  const openvdb::math::Transform& xform,
387  const GU_Detail& detail,
388  const GA_PointGroup* pointGroup = NULL)
389 {
390 #if (UT_MAJOR_VERSION_INT >= 14)
391 
392  std::vector<const GA_Primitive*> packed;
393  GU_VDBPointToolsInternal::getPackedPrimitiveOffsets(detail, packed);
394 
395  if (!packed.empty()) {
396  GU_VDBPointToolsInternal::PackedMaskConstructor op(packed, xform);
397  tbb::parallel_reduce(tbb::blocked_range<size_t>(0, packed.size()), op);
398  return op.getMaskGrid();
399  }
400 
401 #endif
402 
403  GU_VDBPointList<openvdb::Vec3R> points( detail, pointGroup );
404  return openvdb::tools::createPointMask( points, xform );
405 }
406 
407 
408 /// @brief Utility method to construct a PointIndexGrid that stores
409 /// Houdini geometry offsets.
410 ///
411 /// @note PointIndexGrid's that store Houdini geometry offsets are not
412 /// safe to write to disk, offsets are not guaranteed to be immutable
413 /// under defragmentation operations or I/O.
414 inline openvdb::tools::PointIndexGrid::Ptr
416  const openvdb::math::Transform& xform,
417  const GU_Detail& detail,
418  const GA_PointGroup* pointGroup = NULL)
419 {
420  GU_VDBPointList<openvdb::Vec3s> points(detail, pointGroup);
421 
422  openvdb::tools::PointIndexGrid::Ptr grid =
423  openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(points, xform);
424 
425  GUvdbConvertIndexToOffset(grid->tree(), points);
426 
427  return grid;
428 }
429 
430 
431 #endif // GU_VDBPOINTTOOLS_H_HAS_BEEN_INCLUDED
432 
433 // Copyright (c) 2012-2016 DreamWorks Animation LLC
434 // All rights reserved. This software is distributed under the
435 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
Space-partitioning acceleration structure for particles, points with radius. Partitions particle indi...
This tool produces a grid where every voxel that contains a point is active. It employes thread-local...
ParticleAtlas< PointIndexGrid > ParticleIndexAtlas
openvdb::MaskGrid::Ptr GUvdbCreatePointMaskGrid(const openvdb::math::Transform &xform, const GU_Detail &detail, const GA_PointGroup *pointGroup=NULL)
Utility method to construct a boolean PointMaskGrid.
GLsizei GLenum const void * indices
Definition: glcorearb.h:405
static Ptr create(const GU_Detail &detail, const GA_PointGroup *group=NULL)
PointArrayType const *const mPointList
GLenum GLint * range
Definition: glcorearb.h:1924
Iteration over a range of elements.
Definition: GA_Iterator.h:28
void getRadiusFromOffset(const GA_Offset offset, ScalarType &r) const
void getVelocity(size_t n, PosType &v) const
const GLdouble * v
Definition: glcorearb.h:836
bool blockAdvance(GA_Offset &start, GA_Offset &end)
GLuint start
Definition: glcorearb.h:474
GA_Offset offsetFromIndex(size_t n) const
void getRadius(size_t n, ScalarType &r) const
void operator()(LeafT &leaf, size_t) const
uint64 value_type
Definition: GA_PrimCompat.h:29
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
void getPosFromOffset(const GA_Offset offset, PosType &xyz) const
bool isValid() const
Test to see if the attribute reference refers to a valid attribute.
VectorType PosType
A range of elements in an index-map.
Definition: GA_Range.h:42
#define GEO_STD_ATTRIB_VELOCITY
Definition: GEO_Detail.h:82
GA_Size GA_Offset
Definition: GA_Types.h:617
hboost::shared_ptr< const GU_VDBPointList > ConstPtr
PosType::value_type ScalarType
SYS_FORCE_INLINE const_iterator end() const
GLdouble n
Definition: glcorearb.h:2007
bool hasVelocity() const
bool unpack(GU_Detail &dest) const
void bind(const GA_Detail *gdp, GA_AttributeOwner owner, const UT_StringRef &name, int minsize=1)
GA_Iterator begin() const
MaskGrid::Ptr createPointMask(const PointListT &points, const math::Transform &xform)
Return a MaskGrid where each binary voxel value is on if the voxel contains one (or more) points (i...
Definition: PointsToMask.h:116
This class provides a way to manage a reference to an attribute permitting Read-Only access...
Grid< MaskTree > MaskGrid
Definition: openvdb.h:75
GLuint GLuint end
Definition: glcorearb.h:474
GLintptr offset
Definition: glcorearb.h:664
static GA_Size countPackedPrimitives(const GU_Detail &gdp)
Convenience method to return the number of packed primitives.
hboost::shared_ptr< GU_VDBPointList > Ptr
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
Definition: GA_Handle.h:194
GLboolean * data
Definition: glcorearb.h:130
bool unpackWithContext(GU_Detail &dest, GU_PackedContext &context) const
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
void GUvdbConvertIndexToOffset(PointIndexTreeType &tree, const PointArrayType &points)
Utility method to change point indices into Houdini geometry offsets.
A list of primitives.
SYS_FORCE_INLINE bool isValid() const
Definition: GA_Handle.h:185
void getPos(size_t n, PosType &xyz) const
SYS_FORCE_INLINE bool isTrivialMap() const
Definition: GA_IndexMap.h:288
const GA_Attribute * findFloatTuple(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
openvdb::tools::PointIndexGrid::Ptr GUvdbCreatePointIndexGrid(const openvdb::math::Transform &xform, const GU_Detail &detail, const GA_PointGroup *pointGroup=NULL)
Utility method to construct a PointIndexGrid.
SYS_FORCE_INLINE const GA_Primitive * get(GA_Offset off) const
Houdini point attribute wrapper.
openvdb::tools::ParticleIndexAtlas::Ptr GUvdbCreateParticleAtlas(const double minVoxelSize, const ParticleArrayType &particles)
Utility method to construct a ParticleAtals.
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
SYS_FORCE_INLINE GA_Offset offsetFromIndex(GA_Index ordered_index) const
Definition: GA_IndexMap.h:117
void getVelocityFromOffset(const GA_Offset offset, PosType &v) const
GA_API const UT_StringHolder N
const GA_PrimitiveList & getPrimitiveList() const
Definition: GA_Detail.h:715
GU_VDBPointList< openvdb::Vec3s >::Ptr GUvdbCreatePointList(const GU_Detail &detail, const GA_PointGroup *pointGroup=NULL)
Utility method to construct a GU_VDBPointList.
size_t size() const
GU_ConstDetailHandle getPackedDetail() const
#define GEO_STD_ATTRIB_PSCALE
Definition: GEO_Detail.h:102
GLboolean r
Definition: glcorearb.h:1221
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
Definition: GA_Detail.h:1619
openvdb::tools::PointIndexGrid::Ptr GUvdbCreatePointOffsetGrid(const openvdb::math::Transform &xform, const GU_Detail &detail, const GA_PointGroup *pointGroup=NULL)
Utility method to construct a PointIndexGrid that stores Houdini geometry offsets.
virtual void getFullTransform4(UT_Matrix4D &xform) const
GU_VDBPointList(const GU_Detail &detail, const GA_PointGroup *group=NULL)
static bool isPackedPrimitive(const GA_PrimitiveDefinition &pdef)
IndexToOffsetOp(const PointArrayType &points)
bool hasRadius() const
const GA_Attribute * getAttribute() const