OpenVDB  4.0.1
PointDataGrid.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 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 //
30 
38 
39 #ifndef OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
40 #define OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
41 
42 #include <openvdb/Grid.h>
43 #include <openvdb/tree/Tree.h>
44 #include <openvdb/tree/LeafNode.h>
46 #include "AttributeArray.h"
47 #include "AttributeArrayString.h"
48 #include "AttributeGroup.h"
49 #include "AttributeSet.h"
50 #include "StreamCompression.h"
51 #include <type_traits> // std::is_same
52 #include <utility> // std::pair, std::make_pair
53 
54 
55 class TestPointDataLeaf;
56 
57 namespace openvdb {
59 namespace OPENVDB_VERSION_NAME {
60 
61 namespace io
62 {
63 
66 template<>
67 inline void
68 readCompressedValues( std::istream& is, PointDataIndex32* destBuf, Index destCount,
69  const util::NodeMask<3>& /*valueMask*/, bool /*fromHalf*/)
70 {
72 
73  const bool seek = destBuf == nullptr;
74 
75  const size_t destBytes = destCount*sizeof(PointDataIndex32);
76  const size_t maximumBytes = std::numeric_limits<uint16_t>::max();
77  if (destBytes >= maximumBytes) {
78  OPENVDB_THROW(openvdb::IoError, "Cannot read more than " <<
79  maximumBytes << " bytes in voxel values.")
80  }
81 
82  uint16_t bytes16;
83 
85 
86  if (seek && meta) {
87  // buffer size temporarily stored in the StreamMetadata pass
88  // to avoid having to perform an expensive disk read for 2-bytes
89  bytes16 = static_cast<uint16_t>(meta->pass());
90  // seek over size of the compressed buffer
91  is.seekg(sizeof(uint16_t), std::ios_base::cur);
92  }
93  else {
94  // otherwise read from disk
95  is.read(reinterpret_cast<char*>(&bytes16), sizeof(uint16_t));
96  }
97 
98  if (bytes16 == std::numeric_limits<uint16_t>::max()) {
99  // read or seek uncompressed data
100  if (seek) {
101  is.seekg(destBytes, std::ios_base::cur);
102  }
103  else {
104  is.read(reinterpret_cast<char*>(destBuf), destBytes);
105  }
106  }
107  else {
108  // read or seek uncompressed data
109  if (seek) {
110  is.seekg(int(bytes16), std::ios_base::cur);
111  }
112  else {
113  // decompress into the destination buffer
114  std::unique_ptr<char[]> bloscBuffer(new char[int(bytes16)]);
115  is.read(bloscBuffer.get(), bytes16);
116  std::unique_ptr<char[]> buffer = bloscDecompress( bloscBuffer.get(),
117  destBytes,
118  /*resize=*/false);
119  std::memcpy(destBuf, buffer.get(), destBytes);
120  }
121  }
122 }
123 
126 template<>
127 inline void
128 writeCompressedValues( std::ostream& os, PointDataIndex32* srcBuf, Index srcCount,
129  const util::NodeMask<3>& /*valueMask*/,
130  const util::NodeMask<3>& /*childMask*/, bool /*toHalf*/)
131 {
133 
134  const size_t srcBytes = srcCount*sizeof(PointDataIndex32);
135  const size_t maximumBytes = std::numeric_limits<uint16_t>::max();
136  if (srcBytes >= maximumBytes) {
137  OPENVDB_THROW(openvdb::IoError, "Cannot write more than " <<
138  maximumBytes << " bytes in voxel values.")
139  }
140 
141  const char* charBuffer = reinterpret_cast<const char*>(srcBuf);
142 
143  size_t compressedBytes;
144  std::unique_ptr<char[]> buffer = bloscCompress( charBuffer, srcBytes,
145  compressedBytes, /*resize=*/false);
146 
147  if (compressedBytes > 0) {
148  auto bytes16 = static_cast<uint16_t>(compressedBytes); // clamp to 16-bit unsigned integer
149  os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
150  os.write(reinterpret_cast<const char*>(buffer.get()), compressedBytes);
151  }
152  else {
153  auto bytes16 = static_cast<uint16_t>(maximumBytes); // max value indicates uncompressed
154  os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
155  os.write(reinterpret_cast<const char*>(srcBuf), srcBytes);
156  }
157 }
158 
159 template <typename T>
160 inline void
161 writeCompressedValuesSize(std::ostream& os, const T* srcBuf, Index srcCount)
162 {
164 
165  const size_t srcBytes = srcCount*sizeof(T);
166  const size_t maximumBytes = std::numeric_limits<uint16_t>::max();
167  if (srcBytes >= maximumBytes) {
168  OPENVDB_THROW(openvdb::IoError, "Cannot write more than " <<
169  maximumBytes << " bytes in voxel values.")
170  }
171 
172  const char* charBuffer = reinterpret_cast<const char*>(srcBuf);
173 
174  // calculate voxel buffer size after compression
175  size_t compressedBytes = bloscCompressedSize(charBuffer, srcBytes);
176 
177  if (compressedBytes > 0) {
178  auto bytes16 = static_cast<uint16_t>(compressedBytes); // clamp to 16-bit unsigned integer
179  os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
180  }
181  else {
182  auto bytes16 = static_cast<uint16_t>(maximumBytes); // max value indicates uncompressed
183  os.write(reinterpret_cast<const char*>(&bytes16), sizeof(uint16_t));
184  }
185 }
186 
187 } // namespace io
188 
189 
190 // forward declaration
191 namespace tree {
192  template<Index, typename> struct SameLeafConfig;
193 }
194 
195 
197 
198 
199 namespace points {
200 
201 
202 // forward declaration
203 template<typename T, Index Log2Dim> class PointDataLeafNode;
204 
208 
209 
212 
213 
221 template <typename PointDataTreeT>
222 inline AttributeSet::Descriptor::Ptr
223 makeDescriptorUnique(PointDataTreeT& tree);
224 
225 
235 template <typename PointDataTreeT>
236 inline void
237 setStreamingMode(PointDataTreeT& tree, bool on = true);
238 
239 
244 template <typename PointDataTreeT>
245 inline void
246 prefetch(PointDataTreeT& tree);
247 
248 
250 
251 
252 template <typename T, Index Log2Dim>
253 class PointDataLeafNode : public tree::LeafNode<T, Log2Dim>, io::MultiPass {
254 
255 public:
257  using Ptr = std::shared_ptr<PointDataLeafNode>;
258 
259  using ValueType = T;
260  using ValueTypePair = std::pair<ValueType, ValueType>;
261  using IndexArray = std::vector<ValueType>;
262 
263  using Descriptor = AttributeSet::Descriptor;
264 
266 
267  // The following methods had to be copied from the LeafNode class
268  // to make the derived PointDataLeafNode class compatible with the tree structure.
269 
272 
273  using BaseLeaf::LOG2DIM;
274  using BaseLeaf::TOTAL;
275  using BaseLeaf::DIM;
276  using BaseLeaf::NUM_VALUES;
277  using BaseLeaf::NUM_VOXELS;
278  using BaseLeaf::SIZE;
279  using BaseLeaf::LEVEL;
280 
283  : mAttributeSet(new AttributeSet) { }
284 
285  ~PointDataLeafNode() = default;
286 
288  explicit PointDataLeafNode(const PointDataLeafNode& other)
289  : BaseLeaf(other)
290  , mAttributeSet(new AttributeSet(*other.mAttributeSet)) { }
291 
293  explicit
294  PointDataLeafNode(const Coord& coords, const T& value = zeroVal<T>(), bool active = false)
295  : BaseLeaf(coords, zeroVal<T>(), active)
296  , mAttributeSet(new AttributeSet) { assertNonModifiableUnlessZero(value); }
297 
300  PointDataLeafNode(const PointDataLeafNode& other, const Coord& coords,
301  const T& value = zeroVal<T>(), bool active = false)
302  : BaseLeaf(coords, zeroVal<T>(), active)
303  , mAttributeSet(new AttributeSet(*other.mAttributeSet))
304  {
305  assertNonModifiableUnlessZero(value);
306  }
307 
308  // Copy-construct from a PointIndexLeafNode with the same configuration but a different ValueType.
309  template<typename OtherValueType>
311  : BaseLeaf(other)
312  , mAttributeSet(new AttributeSet) { }
313 
314  // Copy-construct from a LeafNode with the same configuration but a different ValueType.
315  // Used for topology copies - explicitly sets the value (background) to zeroVal
316  template <typename ValueType>
318  : BaseLeaf(other, zeroVal<T>(), TopologyCopy())
319  , mAttributeSet(new AttributeSet) { assertNonModifiableUnlessZero(value); }
320 
321  // Copy-construct from a LeafNode with the same configuration but a different ValueType.
322  // Used for topology copies - explicitly sets the on and off value (background) to zeroVal
323  template <typename ValueType>
324  PointDataLeafNode(const tree::LeafNode<ValueType, Log2Dim>& other, const T& /*offValue*/, const T& /*onValue*/, TopologyCopy)
325  : BaseLeaf(other, zeroVal<T>(), zeroVal<T>(), TopologyCopy())
326  , mAttributeSet(new AttributeSet) { }
327 
328 #ifndef OPENVDB_2_ABI_COMPATIBLE
330  const T& value = zeroVal<T>(), bool active = false)
331  : BaseLeaf(PartialCreate(), coords, value, active)
332  , mAttributeSet(new AttributeSet) { assertNonModifiableUnlessZero(value); }
333 #endif
334 
335 public:
336 
338  const AttributeSet& attributeSet() const { return *mAttributeSet; }
339 
341  void initializeAttributes(const Descriptor::Ptr& descriptor, const Index arrayLength);
343  void clearAttributes(const bool updateValueMask = true);
344 
347  bool hasAttribute(const size_t pos) const;
350  bool hasAttribute(const Name& attributeName) const;
351 
358  AttributeArray::Ptr appendAttribute(const Descriptor& expected, Descriptor::Ptr& replacement,
359  const size_t pos, const Index strideOrTotalSize = 1,
360  const bool constantStride = true);
361 
366  void dropAttributes(const std::vector<size_t>& pos,
367  const Descriptor& expected, Descriptor::Ptr& replacement);
370  void reorderAttributes(const Descriptor::Ptr& replacement);
374  void renameAttributes(const Descriptor& expected, Descriptor::Ptr& replacement);
376  void compactAttributes();
377 
383  void replaceAttributeSet(AttributeSet* attributeSet, bool allowMismatchingDescriptors = false);
384 
387  void resetDescriptor(const Descriptor::Ptr& replacement);
388 
392  void setOffsets(const std::vector<ValueType>& offsets, const bool updateValueMask = true);
393 
396  void validateOffsets() const;
397 
400  AttributeArray& attributeArray(const size_t pos);
401  const AttributeArray& attributeArray(const size_t pos) const;
402  const AttributeArray& constAttributeArray(const size_t pos) const;
406  AttributeArray& attributeArray(const Name& attributeName);
407  const AttributeArray& attributeArray(const Name& attributeName) const;
408  const AttributeArray& constAttributeArray(const Name& attributeName) const;
410 
412  GroupHandle groupHandle(const AttributeSet::Descriptor::GroupIndex& index) const;
414  GroupHandle groupHandle(const Name& group) const;
416  GroupWriteHandle groupWriteHandle(const AttributeSet::Descriptor::GroupIndex& index);
418  GroupWriteHandle groupWriteHandle(const Name& name);
419 
421  Index64 pointCount() const;
423  Index64 onPointCount() const;
425  Index64 offPointCount() const;
427  Index64 groupPointCount(const Name& groupName) const;
428 
430  void updateValueMask();
431 
433 
434  void setOffsetOn(Index offset, const ValueType& val);
435  void setOffsetOnly(Index offset, const ValueType& val);
436 
439  template<typename OtherType, Index OtherLog2Dim>
441  return BaseLeaf::hasSameTopology(other);
442  }
443 
446  bool operator==(const PointDataLeafNode& other) const {
447  if(BaseLeaf::operator==(other) != true) return false;
448  return (*this->mAttributeSet == *other.mAttributeSet);
449  }
450 
451  bool operator!=(const PointDataLeafNode& other) const { return !(other == *this); }
452 
454  template<typename AccessorT>
455  void addLeafAndCache(PointDataLeafNode*, AccessorT&) {}
456 
458  PointDataLeafNode* touchLeaf(const Coord&) { return this; }
460  template<typename AccessorT>
461  PointDataLeafNode* touchLeafAndCache(const Coord&, AccessorT&) { return this; }
462 
463  template<typename NodeT, typename AccessorT>
464  NodeT* probeNodeAndCache(const Coord&, AccessorT&)
465  {
467  if (!(std::is_same<NodeT,PointDataLeafNode>::value)) return nullptr;
468  return reinterpret_cast<NodeT*>(this);
470  }
471  PointDataLeafNode* probeLeaf(const Coord&) { return this; }
472  template<typename AccessorT>
473  PointDataLeafNode* probeLeafAndCache(const Coord&, AccessorT&) { return this; }
475 
477  const PointDataLeafNode* probeConstLeaf(const Coord&) const { return this; }
479  template<typename AccessorT>
480  const PointDataLeafNode* probeConstLeafAndCache(const Coord&, AccessorT&) const { return this; }
481  template<typename AccessorT>
482  const PointDataLeafNode* probeLeafAndCache(const Coord&, AccessorT&) const { return this; }
483  const PointDataLeafNode* probeLeaf(const Coord&) const { return this; }
484  template<typename NodeT, typename AccessorT>
485  const NodeT* probeConstNodeAndCache(const Coord&, AccessorT&) const
486  {
488  if (!(std::is_same<NodeT,PointDataLeafNode>::value)) return nullptr;
489  return reinterpret_cast<const NodeT*>(this);
491  }
493 
494  // I/O methods
495 
496  void readTopology(std::istream& is, bool fromHalf = false);
497  void writeTopology(std::ostream& os, bool toHalf = false) const;
498 
499  Index buffers() const;
500 
501  void readBuffers(std::istream& is, bool fromHalf = false);
502  void readBuffers(std::istream& is, const CoordBBox&, bool fromHalf = false);
503  void writeBuffers(std::ostream& os, bool toHalf = false) const;
504 
505 
506  Index64 memUsage() const;
507 
508  void evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels = true) const;
509 
512  CoordBBox getNodeBoundingBox() const;
513 
515 
516  // Disable all write methods to avoid unintentional changes
517  // to the point-array offsets.
518 
520  assert(false && "Cannot modify voxel values in a PointDataTree.");
521  }
522 
523  // some methods silently ignore attempts to modify the
524  // point-array offsets if a zero value is used
525 
527  if (value != zeroVal<T>()) this->assertNonmodifiable();
528  }
529 
530  void setActiveState(const Coord& xyz, bool on) { BaseLeaf::setActiveState(xyz, on); }
531  void setActiveState(Index offset, bool on) { BaseLeaf::setActiveState(offset, on); }
532 
533  void setValueOnly(const Coord&, const ValueType&) { assertNonmodifiable(); }
534  void setValueOnly(Index, const ValueType&) { assertNonmodifiable(); }
535 
536  void setValueOff(const Coord& xyz) { BaseLeaf::setValueOff(xyz); }
537  void setValueOff(Index offset) { BaseLeaf::setValueOff(offset); }
538 
539  void setValueOff(const Coord&, const ValueType&) { assertNonmodifiable(); }
540  void setValueOff(Index, const ValueType&) { assertNonmodifiable(); }
541 
542  void setValueOn(const Coord& xyz) { BaseLeaf::setValueOn(xyz); }
543  void setValueOn(Index offset) { BaseLeaf::setValueOn(offset); }
544 
545  void setValueOn(const Coord&, const ValueType&) { assertNonmodifiable(); }
546  void setValueOn(Index, const ValueType&) { assertNonmodifiable(); }
547 
548  void setValue(const Coord&, const ValueType&) { assertNonmodifiable(); }
549 
550  void setValuesOn() { BaseLeaf::setValuesOn(); }
551  void setValuesOff() { BaseLeaf::setValuesOff(); }
552 
553  template<typename ModifyOp>
554  void modifyValue(Index, const ModifyOp&) { assertNonmodifiable(); }
555 
556  template<typename ModifyOp>
557  void modifyValue(const Coord&, const ModifyOp&) { assertNonmodifiable(); }
558 
559  template<typename ModifyOp>
560  void modifyValueAndActiveState(const Coord&, const ModifyOp&) { assertNonmodifiable(); }
561 
562  // clipping is not yet supported
563  void clip(const CoordBBox&, const ValueType& value) { assertNonModifiableUnlessZero(value); }
564 
565  void fill(const CoordBBox&, const ValueType&, bool);
566  void fill(const ValueType& value) { assertNonModifiableUnlessZero(value); }
567  void fill(const ValueType&, bool);
568 
569  template<typename AccessorT>
570  void setValueOnlyAndCache(const Coord&, const ValueType&, AccessorT&) {assertNonmodifiable();}
571 
572  template<typename ModifyOp, typename AccessorT>
573  void modifyValueAndActiveStateAndCache(const Coord&, const ModifyOp&, AccessorT&) {
574  assertNonmodifiable();
575  }
576 
577  template<typename AccessorT>
578  void setValueOffAndCache(const Coord&, const ValueType&, AccessorT&) { assertNonmodifiable(); }
579 
580  template<typename AccessorT>
581  void setActiveStateAndCache(const Coord& xyz, bool on, AccessorT& parent) {
582  BaseLeaf::setActiveStateAndCache(xyz, on, parent);
583  }
584 
585  void resetBackground(const ValueType&, const ValueType& newBackground) {
586  assertNonModifiableUnlessZero(newBackground);
587  }
588 
589  void signedFloodFill(const ValueType&) { assertNonmodifiable(); }
590  void signedFloodFill(const ValueType&, const ValueType&) { assertNonmodifiable(); }
591 
592  void negate() { assertNonmodifiable(); }
593 
594  friend class ::TestPointDataLeaf;
595 
596  using ValueOn = typename BaseLeaf::ValueOn;
597  using ValueOff = typename BaseLeaf::ValueOff;
598  using ValueAll = typename BaseLeaf::ValueAll;
599 
600 private:
601  std::unique_ptr<AttributeSet> mAttributeSet;
602  uint16_t mVoxelBufferSize = 0;
603 
604 protected:
605  using ChildOn = typename BaseLeaf::ChildOn;
606  using ChildOff = typename BaseLeaf::ChildOff;
607  using ChildAll = typename BaseLeaf::ChildAll;
608 
612 
613  // During topology-only construction, access is needed
614  // to protected/private members of other template instances.
615  template<typename, Index> friend class PointDataLeafNode;
616 
620 
621 public:
623  ValueVoxelCIter beginValueVoxel(const Coord& ijk) const;
624 
625 public:
626 
627 #ifdef _MSC_VER
628  using ValueOnIter = typename BaseLeaf::ValueIter<
630  using ValueOnCIter = typename BaseLeaf::ValueIter<
631  MaskOnIterator, const PointDataLeafNode, const ValueType, ValueOn>;
632  using ValueOffIter = typename BaseLeaf::ValueIter<
633  MaskOffIterator, PointDataLeafNode, const ValueType, ValueOff>;
634  using ValueOffCIter = typename BaseLeaf::ValueIter<
635  MaskOffIterator,const PointDataLeafNode,const ValueType,ValueOff>;
636  using ValueAllIter = typename BaseLeaf::ValueIter<
637  MaskDenseIterator, PointDataLeafNode, const ValueType, ValueAll>;
638  using ValueAllCIter = typename BaseLeaf::ValueIter<
639  MaskDenseIterator,const PointDataLeafNode,const ValueType,ValueAll>;
640  using ChildOnIter = typename BaseLeaf::ChildIter<
641  MaskOnIterator, PointDataLeafNode, ChildOn>;
642  using ChildOnCIter = typename BaseLeaf::ChildIter<
643  MaskOnIterator, const PointDataLeafNode, ChildOn>;
644  using ChildOffIter = typename BaseLeaf::ChildIter<
645  MaskOffIterator, PointDataLeafNode, ChildOff>;
646  using ChildOffCIter = typename BaseLeaf::ChildIter<
647  MaskOffIterator, const PointDataLeafNode, ChildOff>;
648  using ChildAllIter = typename BaseLeaf::DenseIter<
649  PointDataLeafNode, ValueType, ChildAll>;
650  using ChildAllCIter = typename BaseLeaf::DenseIter<
651  const PointDataLeafNode, const ValueType, ChildAll>;
652 #else
653  using ValueOnIter = typename BaseLeaf::template ValueIter<
654  MaskOnIterator, PointDataLeafNode, const ValueType, ValueOn>;
655  using ValueOnCIter = typename BaseLeaf::template ValueIter<
656  MaskOnIterator, const PointDataLeafNode, const ValueType, ValueOn>;
657  using ValueOffIter = typename BaseLeaf::template ValueIter<
658  MaskOffIterator, PointDataLeafNode, const ValueType, ValueOff>;
659  using ValueOffCIter = typename BaseLeaf::template ValueIter<
660  MaskOffIterator,const PointDataLeafNode,const ValueType,ValueOff>;
661  using ValueAllIter = typename BaseLeaf::template ValueIter<
662  MaskDenseIterator, PointDataLeafNode, const ValueType, ValueAll>;
663  using ValueAllCIter = typename BaseLeaf::template ValueIter<
664  MaskDenseIterator,const PointDataLeafNode,const ValueType,ValueAll>;
665  using ChildOnIter = typename BaseLeaf::template ChildIter<
666  MaskOnIterator, PointDataLeafNode, ChildOn>;
667  using ChildOnCIter = typename BaseLeaf::template ChildIter<
668  MaskOnIterator, const PointDataLeafNode, ChildOn>;
669  using ChildOffIter = typename BaseLeaf::template ChildIter<
670  MaskOffIterator, PointDataLeafNode, ChildOff>;
671  using ChildOffCIter = typename BaseLeaf::template ChildIter<
672  MaskOffIterator, const PointDataLeafNode, ChildOff>;
673  using ChildAllIter = typename BaseLeaf::template DenseIter<
674  PointDataLeafNode, ValueType, ChildAll>;
675  using ChildAllCIter = typename BaseLeaf::template DenseIter<
676  const PointDataLeafNode, const ValueType, ChildAll>;
677 #endif
678 
683 
685  IndexAllIter beginIndexAll() const;
686  IndexOnIter beginIndexOn() const;
687  IndexOffIter beginIndexOff() const;
688 
689  template<typename IterT, typename FilterT>
690  IndexIter<IterT, FilterT> beginIndex(const FilterT& filter) const;
691 
693  template<typename FilterT>
694  IndexIter<ValueAllCIter, FilterT> beginIndexAll(const FilterT& filter) const;
695  template<typename FilterT>
696  IndexIter<ValueOnCIter, FilterT> beginIndexOn(const FilterT& filter) const;
697  template<typename FilterT>
698  IndexIter<ValueOffCIter, FilterT> beginIndexOff(const FilterT& filter) const;
699 
701  IndexVoxelIter beginIndexVoxel(const Coord& ijk) const;
702 
704  template<typename FilterT>
705  IndexIter<ValueVoxelCIter, FilterT> beginIndexVoxel(const Coord& ijk, const FilterT& filter) const;
706 
707 #define VMASK_ this->getValueMask()
708  ValueOnCIter cbeginValueOn() const { return ValueOnCIter(VMASK_.beginOn(), this); }
709  ValueOnCIter beginValueOn() const { return ValueOnCIter(VMASK_.beginOn(), this); }
710  ValueOnIter beginValueOn() { return ValueOnIter(VMASK_.beginOn(), this); }
711  ValueOffCIter cbeginValueOff() const { return ValueOffCIter(VMASK_.beginOff(), this); }
712  ValueOffCIter beginValueOff() const { return ValueOffCIter(VMASK_.beginOff(), this); }
713  ValueOffIter beginValueOff() { return ValueOffIter(VMASK_.beginOff(), this); }
714  ValueAllCIter cbeginValueAll() const { return ValueAllCIter(VMASK_.beginDense(), this); }
715  ValueAllCIter beginValueAll() const { return ValueAllCIter(VMASK_.beginDense(), this); }
716  ValueAllIter beginValueAll() { return ValueAllIter(VMASK_.beginDense(), this); }
717 
718  ValueOnCIter cendValueOn() const { return ValueOnCIter(VMASK_.endOn(), this); }
719  ValueOnCIter endValueOn() const { return ValueOnCIter(VMASK_.endOn(), this); }
720  ValueOnIter endValueOn() { return ValueOnIter(VMASK_.endOn(), this); }
721  ValueOffCIter cendValueOff() const { return ValueOffCIter(VMASK_.endOff(), this); }
722  ValueOffCIter endValueOff() const { return ValueOffCIter(VMASK_.endOff(), this); }
723  ValueOffIter endValueOff() { return ValueOffIter(VMASK_.endOff(), this); }
724  ValueAllCIter cendValueAll() const { return ValueAllCIter(VMASK_.endDense(), this); }
725  ValueAllCIter endValueAll() const { return ValueAllCIter(VMASK_.endDense(), this); }
726  ValueAllIter endValueAll() { return ValueAllIter(VMASK_.endDense(), this); }
727 
728  ChildOnCIter cbeginChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
729  ChildOnCIter beginChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
730  ChildOnIter beginChildOn() { return ChildOnIter(VMASK_.endOn(), this); }
731  ChildOffCIter cbeginChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
732  ChildOffCIter beginChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
733  ChildOffIter beginChildOff() { return ChildOffIter(VMASK_.endOff(), this); }
734  ChildAllCIter cbeginChildAll() const { return ChildAllCIter(VMASK_.beginDense(), this); }
735  ChildAllCIter beginChildAll() const { return ChildAllCIter(VMASK_.beginDense(), this); }
736  ChildAllIter beginChildAll() { return ChildAllIter(VMASK_.beginDense(), this); }
737 
738  ChildOnCIter cendChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
739  ChildOnCIter endChildOn() const { return ChildOnCIter(VMASK_.endOn(), this); }
740  ChildOnIter endChildOn() { return ChildOnIter(VMASK_.endOn(), this); }
741  ChildOffCIter cendChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
742  ChildOffCIter endChildOff() const { return ChildOffCIter(VMASK_.endOff(), this); }
743  ChildOffIter endChildOff() { return ChildOffIter(VMASK_.endOff(), this); }
744  ChildAllCIter cendChildAll() const { return ChildAllCIter(VMASK_.endDense(), this); }
745  ChildAllCIter endChildAll() const { return ChildAllCIter(VMASK_.endDense(), this); }
746  ChildAllIter endChildAll() { return ChildAllIter(VMASK_.endDense(), this); }
747 #undef VMASK_
748 }; // struct PointDataLeafNode
749 
751 
752 // PointDataLeafNode implementation
753 
754 template<typename T, Index Log2Dim>
755 inline void
756 PointDataLeafNode<T, Log2Dim>::initializeAttributes(const Descriptor::Ptr& descriptor, const Index arrayLength)
757 {
758  if (descriptor->size() != 1 ||
759  descriptor->find("P") == AttributeSet::INVALID_POS ||
760  descriptor->valueType(0) != typeNameAsString<Vec3f>())
761  {
762  OPENVDB_THROW(IndexError, "Initializing attributes only allowed with one Vec3f position attribute.");
763  }
764 
765  mAttributeSet.reset(new AttributeSet(descriptor, arrayLength));
766 }
767 
768 template<typename T, Index Log2Dim>
769 inline void
771 {
772  mAttributeSet.reset(new AttributeSet(*mAttributeSet, 0));
773 
774  // zero voxel values
775 
776  for (Index n = 0; n < LeafNodeType::NUM_VALUES; n++) {
777  this->setOffsetOnly(n, 0);
778  }
779 
780  // if updateValueMask, also de-activate all voxels
781 
782  if (updateValueMask) this->setValuesOff();
783 }
784 
785 template<typename T, Index Log2Dim>
786 inline bool
788 {
789  return pos < mAttributeSet->size();
790 }
791 
792 template<typename T, Index Log2Dim>
793 inline bool
795 {
796  const size_t pos = mAttributeSet->find(attributeName);
797  return pos != AttributeSet::INVALID_POS;
798 }
799 
800 template<typename T, Index Log2Dim>
801 inline AttributeArray::Ptr
802 PointDataLeafNode<T, Log2Dim>::appendAttribute( const Descriptor& expected, Descriptor::Ptr& replacement,
803  const size_t pos, const Index strideOrTotalSize,
804  const bool constantStride)
805 {
806  return mAttributeSet->appendAttribute(expected, replacement, pos, strideOrTotalSize, constantStride);
807 }
808 
809 template<typename T, Index Log2Dim>
810 inline void
811 PointDataLeafNode<T, Log2Dim>::dropAttributes(const std::vector<size_t>& pos,
812  const Descriptor& expected, Descriptor::Ptr& replacement)
813 {
814  mAttributeSet->dropAttributes(pos, expected, replacement);
815 }
816 
817 template<typename T, Index Log2Dim>
818 inline void
819 PointDataLeafNode<T, Log2Dim>::reorderAttributes(const Descriptor::Ptr& replacement)
820 {
821  mAttributeSet->reorderAttributes(replacement);
822 }
823 
824 template<typename T, Index Log2Dim>
825 inline void
826 PointDataLeafNode<T, Log2Dim>::renameAttributes(const Descriptor& expected, Descriptor::Ptr& replacement)
827 {
828  mAttributeSet->renameAttributes(expected, replacement);
829 }
830 
831 template<typename T, Index Log2Dim>
832 inline void
834 {
835  for (size_t i = 0; i < mAttributeSet->size(); i++) {
836  AttributeArray* array = mAttributeSet->get(i);
837  array->compact();
838  }
839 }
840 
841 template<typename T, Index Log2Dim>
842 inline void
843 PointDataLeafNode<T, Log2Dim>::replaceAttributeSet(AttributeSet* attributeSet, bool allowMismatchingDescriptors)
844 {
845  if (!attributeSet) {
846  OPENVDB_THROW(ValueError, "Cannot replace with a null attribute set");
847  }
848 
849  if (!allowMismatchingDescriptors && mAttributeSet->descriptor() != attributeSet->descriptor()) {
850  OPENVDB_THROW(ValueError, "Attribute set descriptors are not equal.");
851  }
852 
853  mAttributeSet.reset(attributeSet);
854 }
855 
856 template<typename T, Index Log2Dim>
857 inline void
858 PointDataLeafNode<T, Log2Dim>::resetDescriptor(const Descriptor::Ptr& replacement)
859 {
860  mAttributeSet->resetDescriptor(replacement);
861 }
862 
863 template<typename T, Index Log2Dim>
864 inline void
865 PointDataLeafNode<T, Log2Dim>::setOffsets(const std::vector<ValueType>& offsets, const bool updateValueMask)
866 {
867  if (offsets.size() != LeafNodeType::NUM_VALUES) {
868  OPENVDB_THROW(ValueError, "Offset vector size doesn't match number of voxels.")
869  }
870 
871  for (Index index = 0; index < offsets.size(); ++index) {
872  setOffsetOnly(index, offsets[index]);
873  }
874 
875  if (updateValueMask) this->updateValueMask();
876 }
877 
878 template<typename T, Index Log2Dim>
879 inline void
881 {
882  // Ensure all of the offset values are monotonically increasing
883  for (Index index = 1; index < BaseLeaf::SIZE; ++index) {
884  if (this->getValue(index-1) > this->getValue(index)) {
885  OPENVDB_THROW(ValueError, "Voxel offset values are not monotonically increasing");
886  }
887  }
888 
889  // Ensure all attribute arrays are of equal length
890  for (size_t attributeIndex = 1; attributeIndex < mAttributeSet->size(); ++attributeIndex ) {
891  if (mAttributeSet->getConst(attributeIndex-1)->size() != mAttributeSet->getConst(attributeIndex)->size()) {
892  OPENVDB_THROW(ValueError, "Attribute arrays have inconsistent length");
893  }
894  }
895 
896  // Ensure the last voxel's offset value matches the size of each attribute array
897  if (mAttributeSet->size() > 0 && this->getValue(BaseLeaf::SIZE-1) != mAttributeSet->getConst(0)->size()) {
898  OPENVDB_THROW(ValueError, "Last voxel offset value does not match attribute array length");
899  }
900 }
901 
902 template<typename T, Index Log2Dim>
903 inline AttributeArray&
905 {
906  if (pos >= mAttributeSet->size()) OPENVDB_THROW(LookupError, "Attribute Out Of Range - " << pos);
907  return *mAttributeSet->get(pos);
908 }
909 
910 template<typename T, Index Log2Dim>
911 inline const AttributeArray&
913 {
914  if (pos >= mAttributeSet->size()) OPENVDB_THROW(LookupError, "Attribute Out Of Range - " << pos);
915  return *mAttributeSet->getConst(pos);
916 }
917 
918 template<typename T, Index Log2Dim>
919 inline const AttributeArray&
921 {
922  return this->attributeArray(pos);
923 }
924 
925 template<typename T, Index Log2Dim>
926 inline AttributeArray&
928 {
929  const size_t pos = mAttributeSet->find(attributeName);
930  if (pos == AttributeSet::INVALID_POS) OPENVDB_THROW(LookupError, "Attribute Not Found - " << attributeName);
931  return *mAttributeSet->get(pos);
932 }
933 
934 template<typename T, Index Log2Dim>
935 inline const AttributeArray&
937 {
938  const size_t pos = mAttributeSet->find(attributeName);
939  if (pos == AttributeSet::INVALID_POS) OPENVDB_THROW(LookupError, "Attribute Not Found - " << attributeName);
940  return *mAttributeSet->getConst(pos);
941 }
942 
943 template<typename T, Index Log2Dim>
944 inline const AttributeArray&
946 {
947  return this->attributeArray(attributeName);
948 }
949 
950 template<typename T, Index Log2Dim>
951 inline GroupHandle
952 PointDataLeafNode<T, Log2Dim>::groupHandle(const AttributeSet::Descriptor::GroupIndex& index) const
953 {
954  const AttributeArray& array = this->attributeArray(index.first);
955  assert(isGroup(array));
956 
957  const GroupAttributeArray& groupArray = GroupAttributeArray::cast(array);
958 
959  return GroupHandle(groupArray, index.second);
960 }
961 
962 template<typename T, Index Log2Dim>
963 inline GroupHandle
965 {
966  const AttributeSet::Descriptor::GroupIndex index = this->attributeSet().groupIndex(name);
967  return this->groupHandle(index);
968 }
969 
970 template<typename T, Index Log2Dim>
971 inline GroupWriteHandle
972 PointDataLeafNode<T, Log2Dim>::groupWriteHandle(const AttributeSet::Descriptor::GroupIndex& index)
973 {
974  AttributeArray& array = this->attributeArray(index.first);
975  assert(isGroup(array));
976 
977  GroupAttributeArray& groupArray = GroupAttributeArray::cast(array);
978 
979  return GroupWriteHandle(groupArray, index.second);
980 }
981 
982 template<typename T, Index Log2Dim>
983 inline GroupWriteHandle
985 {
986  const AttributeSet::Descriptor::GroupIndex index = this->attributeSet().groupIndex(name);
987  return this->groupWriteHandle(index);
988 }
989 
990 template<typename T, Index Log2Dim>
991 template<typename ValueIterT, typename FilterT>
993 PointDataLeafNode<T, Log2Dim>::beginIndex(const FilterT& filter) const
994 {
995  using IterTraitsT = tree::IterTraits<LeafNodeType, ValueIterT>;
996 
997  // construct the value iterator and reset the filter to use this leaf
998 
999  ValueIterT valueIter = IterTraitsT::begin(*this);
1000  FilterT newFilter(filter);
1001  newFilter.reset(*this);
1002 
1003  return IndexIter<ValueIterT, FilterT>(valueIter, newFilter);
1004 }
1005 
1006 template<typename T, Index Log2Dim>
1007 template<typename FilterT>
1010 {
1011  return this->beginIndex<ValueAllCIter, FilterT>(filter);
1012 }
1013 
1014 template<typename T, Index Log2Dim>
1015 template<typename FilterT>
1018 {
1019  return this->beginIndex<ValueOnCIter, FilterT>(filter);
1020 }
1021 
1022 template<typename T, Index Log2Dim>
1023 template<typename FilterT>
1026 {
1027  return this->beginIndex<ValueOffCIter, FilterT>(filter);
1028 }
1029 
1030 template<typename T, Index Log2Dim>
1031 inline IndexIter<typename PointDataLeafNode<T, Log2Dim>::ValueAllCIter, NullFilter>
1033 {
1034  NullFilter filter;
1035  return this->beginIndex<ValueAllCIter, NullFilter>(filter);
1036 }
1037 
1038 template<typename T, Index Log2Dim>
1041 {
1042  NullFilter filter;
1043  return this->beginIndex<ValueOnCIter, NullFilter>(filter);
1044 }
1045 
1046 template<typename T, Index Log2Dim>
1049 {
1050  NullFilter filter;
1051  return this->beginIndex<ValueOffCIter, NullFilter>(filter);
1052 }
1053 
1054 template<typename T, Index Log2Dim>
1055 inline ValueVoxelCIter
1057 {
1058  const Index index = LeafNodeType::coordToOffset(ijk);
1059  assert(index < BaseLeaf::SIZE);
1060  const ValueType end = this->getValue(index);
1061  const ValueType start = (index == 0) ? ValueType(0) : this->getValue(index - 1);
1062  return ValueVoxelCIter(start, end);
1063 }
1064 
1065 template<typename T, Index Log2Dim>
1068 {
1069  ValueVoxelCIter iter = this->beginValueVoxel(ijk);
1070  return IndexVoxelIter(iter, NullFilter());
1071 }
1072 
1073 template<typename T, Index Log2Dim>
1074 template<typename FilterT>
1076 PointDataLeafNode<T, Log2Dim>::beginIndexVoxel(const Coord& ijk, const FilterT& filter) const
1077 {
1078  ValueVoxelCIter iter = this->beginValueVoxel(ijk);
1079  FilterT newFilter(filter);
1080  newFilter.reset(*this);
1081  return IndexIter<ValueVoxelCIter, FilterT>(iter, newFilter);
1082 }
1083 
1084 template<typename T, Index Log2Dim>
1085 inline Index64
1087 {
1088  return iterCount(this->beginIndexAll());
1089 }
1090 
1091 template<typename T, Index Log2Dim>
1092 inline Index64
1094 {
1095  if (this->isEmpty()) return 0;
1096  else if (this->isDense()) return this->pointCount();
1097  return iterCount(this->beginIndexOn());
1098 }
1099 
1100 template<typename T, Index Log2Dim>
1101 inline Index64
1103 {
1104  if (this->isEmpty()) return this->pointCount();
1105  else if (this->isDense()) return 0;
1106  return iterCount(this->beginIndexOff());
1107 }
1108 
1109 template<typename T, Index Log2Dim>
1110 inline Index64
1112 {
1113  GroupFilter filter(groupName);
1114  return iterCount(this->beginIndexAll(filter));
1115 }
1116 
1117 template<typename T, Index Log2Dim>
1118 inline void
1120 {
1121  ValueType start = 0, end = 0;
1122  for (Index n = 0; n < LeafNodeType::NUM_VALUES; n++) {
1123  end = this->getValue(n);
1124  this->setValueMask(n, (end - start) > 0);
1125  start = end;
1126  }
1127 }
1128 
1129 template<typename T, Index Log2Dim>
1130 inline void
1132 {
1133  this->buffer().setValue(offset, val);
1134  this->setValueMaskOn(offset);
1135 }
1136 
1137 template<typename T, Index Log2Dim>
1138 inline void
1140 {
1141  this->buffer().setValue(offset, val);
1142 }
1143 
1144 template<typename T, Index Log2Dim>
1145 inline void
1146 PointDataLeafNode<T, Log2Dim>::readTopology(std::istream& is, bool fromHalf)
1147 {
1148  BaseLeaf::readTopology(is, fromHalf);
1149 }
1150 
1151 template<typename T, Index Log2Dim>
1152 inline void
1153 PointDataLeafNode<T, Log2Dim>::writeTopology(std::ostream& os, bool toHalf) const
1154 {
1155  BaseLeaf::writeTopology(os, toHalf);
1156 }
1157 
1158 template<typename T, Index Log2Dim>
1159 inline Index
1161 {
1162  return Index( /*voxel buffer sizes*/ 1 +
1163  /*voxel buffers*/ 1 +
1164  /*attribute metadata*/ 1 +
1165  /*attribute uniform values*/ mAttributeSet->size() +
1166  /*attribute buffers*/ mAttributeSet->size() +
1167  /*cleanup*/ 1);
1168 }
1169 
1170 template<typename T, Index Log2Dim>
1171 inline void
1172 PointDataLeafNode<T, Log2Dim>::readBuffers(std::istream& is, bool fromHalf)
1173 {
1174  this->readBuffers(is, CoordBBox::inf(), fromHalf);
1175 }
1176 
1177 template<typename T, Index Log2Dim>
1178 inline void
1179 PointDataLeafNode<T, Log2Dim>::readBuffers(std::istream& is, const CoordBBox& /*bbox*/, bool fromHalf)
1180 {
1181  struct Local
1182  {
1183  static compression::PagedInputStream& getOrInsertPagedStream( const io::StreamMetadata::AuxDataMap& auxData,
1184  const Index index)
1185  {
1186  std::string key("paged:" + std::to_string(index));
1187  auto it = auxData.find(key);
1188  if (it != auxData.end()) {
1189  return *(boost::any_cast<compression::PagedInputStream::Ptr>(it->second));
1190  }
1191  else {
1192  compression::PagedInputStream::Ptr pagedStream = std::make_shared<compression::PagedInputStream>();
1193  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[key] = pagedStream;
1194  return *pagedStream;
1195  }
1196  }
1197 
1198  static bool hasMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
1199  {
1200  std::string matchingKey("hasMatchingDescriptor");
1201  auto itMatching = auxData.find(matchingKey);
1202  return itMatching != auxData.end();
1203  }
1204 
1205  static void clearMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
1206  {
1207  std::string matchingKey("hasMatchingDescriptor");
1208  std::string descriptorKey("descriptorPtr");
1209  auto itMatching = auxData.find(matchingKey);
1210  auto itDescriptor = auxData.find(descriptorKey);
1211  if (itMatching != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itMatching);
1212  if (itDescriptor != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
1213  }
1214 
1215  static void insertDescriptor( const io::StreamMetadata::AuxDataMap& auxData,
1216  const Descriptor::Ptr descriptor)
1217  {
1218  std::string descriptorKey("descriptorPtr");
1219  std::string matchingKey("hasMatchingDescriptor");
1220  auto itMatching = auxData.find(matchingKey);
1221  if (itMatching == auxData.end()) {
1222  // if matching bool is not found, insert "true" and the descriptor
1223  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[matchingKey] = true;
1224  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[descriptorKey] = descriptor;
1225  }
1226  }
1227 
1228  static AttributeSet::Descriptor::Ptr retrieveMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
1229  {
1230  std::string descriptorKey("descriptorPtr");
1231  auto itDescriptor = auxData.find(descriptorKey);
1232  assert(itDescriptor != auxData.end());
1233  const Descriptor::Ptr descriptor = boost::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
1234  return descriptor;
1235  }
1236  };
1237 
1239 
1240  if (!meta) {
1241  OPENVDB_THROW(IoError, "Cannot read in a PointDataLeaf without StreamMetadata.");
1242  }
1243 
1244  const Index pass(static_cast<uint16_t>(meta->pass()));
1245  const Index maximumPass(static_cast<uint16_t>(meta->pass() >> 16));
1246 
1247  const Index attributes = (maximumPass - 4) / 2;
1248 
1249  if (pass == 0) {
1250  // pass 0 - voxel data sizes
1251  is.read(reinterpret_cast<char*>(&mVoxelBufferSize), sizeof(uint16_t));
1252  Local::clearMatchingDescriptor(meta->auxData());
1253  }
1254  else if (pass == 1) {
1255  // pass 1 - descriptor and attribute metadata
1256  if (Local::hasMatchingDescriptor(meta->auxData())) {
1257  AttributeSet::Descriptor::Ptr descriptor = Local::retrieveMatchingDescriptor(meta->auxData());
1258  mAttributeSet->resetDescriptor(descriptor, /*allowMismatchingDescriptors=*/true);
1259  }
1260  else {
1261  uint8_t header;
1262  is.read(reinterpret_cast<char*>(&header), sizeof(uint8_t));
1263  mAttributeSet->readDescriptor(is);
1264  if (header == uint8_t(1)) {
1265  AttributeSet::DescriptorPtr descriptor = mAttributeSet->descriptorPtr();
1266  Local::insertDescriptor(meta->auxData(), descriptor);
1267  }
1268  }
1269  mAttributeSet->readMetadata(is);
1270  }
1271  else if (pass < (attributes + 2)) {
1272  // pass 2...n+2 - attribute uniform values
1273  const size_t attributeIndex = pass - 2;
1274  AttributeArray* array = attributeIndex < mAttributeSet->size() ?
1275  mAttributeSet->get(attributeIndex) : nullptr;
1276  if (array) {
1277  compression::PagedInputStream& pagedStream =
1278  Local::getOrInsertPagedStream(meta->auxData(), static_cast<Index>(attributeIndex));
1279  pagedStream.setInputStream(is);
1280  pagedStream.setSizeOnly(true);
1281  array->readPagedBuffers(pagedStream);
1282  }
1283  }
1284  else if (pass == attributes + 2) {
1285  // pass n+2 - voxel data
1286 
1287  const Index passValue(meta->pass());
1288 
1289  // StreamMetadata pass variable used to temporarily store voxel buffer size
1290  io::StreamMetadata& nonConstMeta = const_cast<io::StreamMetadata&>(*meta);
1291  nonConstMeta.setPass(mVoxelBufferSize);
1292 
1293  // readBuffers() calls readCompressedValues specialization above
1294  BaseLeaf::readBuffers(is, fromHalf);
1295 
1296  // pass now reset to original value
1297  nonConstMeta.setPass(passValue);
1298  }
1299  else if (pass < (attributes*2 + 3)) {
1300  // pass n+2..2n+2 - attribute buffers
1301  const Index attributeIndex = pass - attributes - 3;
1302  AttributeArray* array = attributeIndex < mAttributeSet->size() ?
1303  mAttributeSet->get(attributeIndex) : nullptr;
1304  if (array) {
1305  compression::PagedInputStream& pagedStream =
1306  Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
1307  pagedStream.setInputStream(is);
1308  pagedStream.setSizeOnly(false);
1309  array->readPagedBuffers(pagedStream);
1310  }
1311  }
1312 }
1313 
1314 template<typename T, Index Log2Dim>
1315 inline void
1316 PointDataLeafNode<T, Log2Dim>::writeBuffers(std::ostream& os, bool toHalf) const
1317 {
1318  struct Local
1319  {
1320  static void destroyPagedStream(const io::StreamMetadata::AuxDataMap& auxData, const Index index)
1321  {
1322  // if paged stream exists, flush and delete it
1323  std::string key("paged:" + std::to_string(index));
1324  auto it = auxData.find(key);
1325  if (it != auxData.end()) {
1326  compression::PagedOutputStream& stream = *(boost::any_cast<compression::PagedOutputStream::Ptr>(it->second));
1327  stream.flush();
1328  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(it);
1329  }
1330  }
1331 
1332  static compression::PagedOutputStream& getOrInsertPagedStream( const io::StreamMetadata::AuxDataMap& auxData,
1333  const Index index)
1334  {
1335  std::string key("paged:" + std::to_string(index));
1336  auto it = auxData.find(key);
1337  if (it != auxData.end()) {
1338  return *(boost::any_cast<compression::PagedOutputStream::Ptr>(it->second));
1339  }
1340  else {
1341  compression::PagedOutputStream::Ptr pagedStream = std::make_shared<compression::PagedOutputStream>();
1342  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[key] = pagedStream;
1343  return *pagedStream;
1344  }
1345  }
1346 
1347  static void insertDescriptor( const io::StreamMetadata::AuxDataMap& auxData,
1348  const Descriptor::Ptr descriptor)
1349  {
1350  std::string descriptorKey("descriptorPtr");
1351  std::string matchingKey("hasMatchingDescriptor");
1352  auto itMatching = auxData.find(matchingKey);
1353  auto itDescriptor = auxData.find(descriptorKey);
1354  if (itMatching == auxData.end()) {
1355  // if matching bool is not found, insert "true" and the descriptor
1356  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[matchingKey] = true;
1357  assert(itDescriptor == auxData.end());
1358  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[descriptorKey] = descriptor;
1359  }
1360  else {
1361  // if matching bool is found and is false, early exit (a previous descriptor did not match)
1362  bool matching = boost::any_cast<bool>(itMatching->second);
1363  if (!matching) return;
1364  assert(itDescriptor != auxData.end());
1365  // if matching bool is true, check whether the existing descriptor matches the current one and set
1366  // matching bool to false if not
1367  const Descriptor::Ptr existingDescriptor = boost::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
1368  if (*existingDescriptor != *descriptor) {
1369  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData))[matchingKey] = false;
1370  }
1371  }
1372  }
1373 
1374  static bool hasMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
1375  {
1376  std::string matchingKey("hasMatchingDescriptor");
1377  auto itMatching = auxData.find(matchingKey);
1378  // if matching key is not found, no matching descriptor
1379  if (itMatching == auxData.end()) return false;
1380  // if matching key is found and is false, no matching descriptor
1381  if (!boost::any_cast<bool>(itMatching->second)) return false;
1382  return true;
1383  }
1384 
1385  static AttributeSet::Descriptor::Ptr retrieveMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
1386  {
1387  std::string descriptorKey("descriptorPtr");
1388  auto itDescriptor = auxData.find(descriptorKey);
1389  // if matching key is true, however descriptor is not found, it has already been retrieved
1390  if (itDescriptor == auxData.end()) return nullptr;
1391  // otherwise remove it and return it
1392  const Descriptor::Ptr descriptor = boost::any_cast<AttributeSet::Descriptor::Ptr>(itDescriptor->second);
1393  (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
1394  return descriptor;
1395  }
1396 
1397  static void clearMatchingDescriptor(const io::StreamMetadata::AuxDataMap& auxData)
1398  {
1399  std::string matchingKey("hasMatchingDescriptor");
1400  std::string descriptorKey("descriptorPtr");
1401  auto itMatching = auxData.find(matchingKey);
1402  auto itDescriptor = auxData.find(descriptorKey);
1403  if (itMatching != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itMatching);
1404  if (itDescriptor != auxData.end()) (const_cast<io::StreamMetadata::AuxDataMap&>(auxData)).erase(itDescriptor);
1405  }
1406  };
1407 
1409 
1410  if (!meta) {
1411  OPENVDB_THROW(IoError, "Cannot write out a PointDataLeaf without StreamMetadata.");
1412  }
1413 
1414  const Index pass(static_cast<uint16_t>(meta->pass()));
1415 
1416  // leaf traversal analysis deduces the number of passes to perform for this leaf
1417  // then updates the leaf traversal value to ensure all passes will be written
1418 
1419  if (meta->countingPasses()) {
1420  const Index requiredPasses = this->buffers();
1421  if (requiredPasses > pass) {
1422  meta->setPass(requiredPasses);
1423  }
1424  return;
1425  }
1426 
1427  const Index maximumPass(static_cast<uint16_t>(meta->pass() >> 16));
1428  const Index attributes = (maximumPass - 4) / 2;
1429 
1430  if (pass == 0) {
1431  // pass 0 - voxel data sizes
1432  io::writeCompressedValuesSize(os, this->buffer().data(), SIZE);
1433  // track if descriptor is shared or not
1434  Local::insertDescriptor(meta->auxData(), mAttributeSet->descriptorPtr());
1435  }
1436  else if (pass == 1) {
1437  // pass 1 - descriptor and attribute metadata
1438  bool matchingDescriptor = Local::hasMatchingDescriptor(meta->auxData());
1439  if (matchingDescriptor) {
1440  AttributeSet::Descriptor::Ptr descriptor = Local::retrieveMatchingDescriptor(meta->auxData());
1441  if (descriptor) {
1442  // write a header to indicate a shared descriptor
1443  uint8_t header(1);
1444  os.write(reinterpret_cast<const char*>(&header), sizeof(uint8_t));
1445  mAttributeSet->writeDescriptor(os, /*transient=*/false);
1446  }
1447  }
1448  else {
1449  // write a header to indicate a non-shared descriptor
1450  uint8_t header(0);
1451  os.write(reinterpret_cast<const char*>(&header), sizeof(uint8_t));
1452  mAttributeSet->writeDescriptor(os, /*transient=*/false);
1453  }
1454  mAttributeSet->writeMetadata(os, /*transient=*/false, /*paged=*/true);
1455  }
1456  else if (pass < attributes + 2) {
1457  // pass 2...n+2 - attribute buffer sizes
1458  const Index attributeIndex = pass - 2;
1459  // destroy previous paged stream
1460  if (pass > 2) {
1461  Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
1462  }
1463  const AttributeArray* array = attributeIndex < mAttributeSet->size() ?
1464  mAttributeSet->getConst(attributeIndex) : nullptr;
1465  if (array) {
1466  compression::PagedOutputStream& pagedStream =
1467  Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
1468  pagedStream.setOutputStream(os);
1469  pagedStream.setSizeOnly(true);
1470  array->writePagedBuffers(pagedStream, /*outputTransient*/false);
1471  }
1472  }
1473  else if (pass == attributes + 2) {
1474  const Index attributeIndex = pass - 3;
1475  Local::destroyPagedStream(meta->auxData(), attributeIndex);
1476  // pass n+2 - voxel data
1477  BaseLeaf::writeBuffers(os, toHalf);
1478  }
1479  else if (pass < (attributes*2 + 3)) {
1480  // pass n+3...2n+3 - attribute buffers
1481  const Index attributeIndex = pass - attributes - 3;
1482  // destroy previous paged stream
1483  if (pass > attributes + 2) {
1484  Local::destroyPagedStream(meta->auxData(), attributeIndex-1);
1485  }
1486  const AttributeArray* array = attributeIndex < mAttributeSet->size() ?
1487  mAttributeSet->getConst(attributeIndex) : nullptr;
1488  if (array) {
1489  compression::PagedOutputStream& pagedStream =
1490  Local::getOrInsertPagedStream(meta->auxData(), attributeIndex);
1491  pagedStream.setOutputStream(os);
1492  pagedStream.setSizeOnly(false);
1493  array->writePagedBuffers(pagedStream, /*outputTransient*/false);
1494  }
1495  }
1496  else if (pass < buffers()) {
1497  Local::clearMatchingDescriptor(meta->auxData());
1498  // pass 2n+3 - cleanup last paged stream
1499  const Index attributeIndex = pass - attributes - 4;
1500  Local::destroyPagedStream(meta->auxData(), attributeIndex);
1501  }
1502 }
1503 
1504 template<typename T, Index Log2Dim>
1505 inline Index64
1507 {
1508  return BaseLeaf::memUsage() + mAttributeSet->memUsage();
1509 }
1510 
1511 template<typename T, Index Log2Dim>
1512 inline void
1514 {
1515  BaseLeaf::evalActiveBoundingBox(bbox, visitVoxels);
1516 }
1517 
1518 template<typename T, Index Log2Dim>
1519 inline CoordBBox
1521 {
1522  return BaseLeaf::getNodeBoundingBox();
1523 }
1524 
1525 template<typename T, Index Log2Dim>
1526 inline void
1527 PointDataLeafNode<T, Log2Dim>::fill(const CoordBBox& bbox, const ValueType& value, bool active)
1528 {
1529 #ifndef OPENVDB_2_ABI_COMPATIBLE
1530  if (!this->allocate()) return;
1531 #endif
1532 
1533  this->assertNonModifiableUnlessZero(value);
1534 
1535  // active state is permitted to be updated
1536 
1537  for (Int32 x = bbox.min().x(); x <= bbox.max().x(); ++x) {
1538  const Index offsetX = (x & (DIM-1u)) << 2*Log2Dim;
1539  for (Int32 y = bbox.min().y(); y <= bbox.max().y(); ++y) {
1540  const Index offsetXY = offsetX + ((y & (DIM-1u)) << Log2Dim);
1541  for (Int32 z = bbox.min().z(); z <= bbox.max().z(); ++z) {
1542  const Index offset = offsetXY + (z & (DIM-1u));
1543  this->setValueMask(offset, active);
1544  }
1545  }
1546  }
1547 }
1548 
1549 template<typename T, Index Log2Dim>
1550 inline void
1552 {
1553  this->assertNonModifiableUnlessZero(value);
1554 
1555  // active state is permitted to be updated
1556 
1557  if (active) this->setValuesOn();
1558  else this->setValuesOff();
1559 }
1560 
1561 
1563 
1564 
1565 template <typename PointDataTreeT>
1566 inline AttributeSet::Descriptor::Ptr
1567 makeDescriptorUnique(PointDataTreeT& tree)
1568 {
1569  auto leafIter = tree.beginLeaf();
1570  if (!leafIter) return nullptr;
1571 
1572  const AttributeSet::Descriptor& descriptor = leafIter->attributeSet().descriptor();
1573  auto newDescriptor = std::make_shared<AttributeSet::Descriptor>(descriptor);
1574  for (; leafIter; ++leafIter) {
1575  leafIter->resetDescriptor(newDescriptor);
1576  }
1577 
1578  return newDescriptor;
1579 }
1580 
1581 
1582 template <typename PointDataTreeT>
1583 inline void
1584 setStreamingMode(PointDataTreeT& tree, bool on)
1585 {
1586  auto leafIter = tree.beginLeaf();
1587  for (; leafIter; ++leafIter) {
1588  for (size_t i = 0; i < leafIter->attributeSet().size(); i++) {
1589  leafIter->attributeArray(i).setStreaming(on);
1590  }
1591  }
1592 }
1593 
1594 
1595 template <typename PointDataTreeT>
1596 inline void
1597 prefetch(PointDataTreeT& tree)
1598 {
1599  // sequential pre-fetch of out-of-core data for faster performance
1600 
1601  PointDataTree::LeafCIter leafIter = tree.cbeginLeaf();
1602  if (leafIter) {
1603  const size_t attributes = leafIter->attributeSet().size();
1604  // load voxel buffer data
1605  for ( ; leafIter; ++leafIter) {
1606  const PointDataTree::LeafNodeType::Buffer& buffer = leafIter->buffer();
1607  buffer.data();
1608  }
1609  // load attribute data
1610  for (size_t pos = 0; pos < attributes; pos++) {
1611  leafIter = tree.cbeginLeaf();
1612  for ( ; leafIter; ++leafIter) {
1613  if (leafIter->hasAttribute(pos)) {
1614  const AttributeArray& array = leafIter->constAttributeArray(pos);
1615  array.loadData();
1616  }
1617  }
1618  }
1619  }
1620 }
1621 
1622 
1623 namespace internal {
1624 
1628 void initialize();
1629 
1633 void uninitialize();
1634 
1635 }
1636 
1637 
1642 
1643 } // namespace points
1644 
1645 
1647 
1648 
1649 namespace tree
1650 {
1651 
1654 template<Index Dim1, typename T2>
1655 struct SameLeafConfig<Dim1, points::PointDataLeafNode<T2, Dim1>> { static const bool value = true; };
1656 
1657 } // namespace tree
1658 } // namespace OPENVDB_VERSION_NAME
1659 } // namespace openvdb
1660 
1661 #endif // OPENVDB_POINTS_POINT_DATA_GRID_HAS_BEEN_INCLUDED
1662 
1663 // Copyright (c) 2012-2017 DreamWorks Animation LLC
1664 // All rights reserved. This software is distributed under the
1665 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
PointDataLeafNode(const tools::PointIndexLeafNode< OtherValueType, Log2Dim > &other)
Definition: PointDataGrid.h:310
ChildOnCIter beginChildOn() const
Definition: PointDataGrid.h:729
PointDataLeafNode * probeLeaf(const Coord &)
Return a pointer to this node.
Definition: PointDataGrid.h:471
void setValue(const Coord &, const ValueType &)
Definition: PointDataGrid.h:548
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:503
void setValuesOn()
Definition: PointDataGrid.h:550
PointDataLeafNode(const PointDataLeafNode &other)
Construct using deep copy of other PointDataLeafNode.
Definition: PointDataGrid.h:288
void setValuesOff()
Definition: PointDataGrid.h:551
ChildOnCIter cendChildOn() const
Definition: PointDataGrid.h:738
Attribute Group access and filtering for iteration.
typename NodeMaskType::DenseIterator MaskDenseIterator
Definition: PointDataGrid.h:611
const char * typeNameAsString< Vec3f >()
Definition: Types.h:343
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
void setValueOffAndCache(const Coord &, const ValueType &, AccessorT &)
Definition: PointDataGrid.h:578
void prefetch(PointDataTreeT &tree)
Sequentially pre-fetch all delayed-load voxel and attribute data from disk in order to accelerate sub...
Definition: PointDataGrid.h:1597
Int32 z() const
Definition: Coord.h:156
Index64 groupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=false)
Total points in the group in the PointDataTree.
Definition: PointCount.h:237
ValueAllCIter cendValueAll() const
Definition: PointDataGrid.h:724
ValueOffCIter beginValueOff() const
Definition: PointDataGrid.h:712
PointIndex< Index32, 1 > PointDataIndex32
Definition: Types.h:195
PointDataLeafNode(const tree::LeafNode< ValueType, Log2Dim > &other, const T &value, TopologyCopy)
Definition: PointDataGrid.h:317
ChildOnIter beginChildOn()
Definition: PointDataGrid.h:730
std::shared_ptr< Descriptor > DescriptorPtr
Definition: AttributeSet.h:72
Leaf nodes that require multi-pass I/O must inherit from this struct.
Definition: io.h:140
Container for metadata describing how to unserialize grids from and/or serialize grids to a stream (w...
Definition: io.h:56
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
void writeCompressedValuesSize(std::ostream &os, const T *srcBuf, Index srcCount)
Definition: PointDataGrid.h:161
void setValueOn(Index, const ValueType &)
Definition: PointDataGrid.h:546
bool hasSameTopology(const PointDataLeafNode< OtherType, OtherLog2Dim > *other) const
Return true if the given node (which may have a different ValueType than this node) has the same acti...
Definition: PointDataGrid.h:440
void setActiveStateAndCache(const Coord &xyz, bool on, AccessorT &parent)
Definition: PointDataGrid.h:581
std::shared_ptr< PointDataLeafNode > Ptr
Definition: PointDataGrid.h:257
#define VMASK_
Definition: PointDataGrid.h:707
void modifyValueAndActiveStateAndCache(const Coord &, const ModifyOp &, AccessorT &)
Definition: PointDataGrid.h:573
void reorderAttributes(const Descriptor::Ptr &replacement)
Reorder attribute set.
Definition: PointDataGrid.h:819
bool operator==(const PointDataLeafNode &other) const
Definition: PointDataGrid.h:446
ChildOffCIter cbeginChildOff() const
Definition: PointDataGrid.h:731
void modifyValueAndActiveState(const Coord &, const ModifyOp &)
Definition: PointDataGrid.h:560
Definition: PointDataGrid.h:203
ValueOnCIter cendValueOn() const
Definition: PointDataGrid.h:718
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:266
OPENVDB_API void bloscCompress(char *compressedBuffer, size_t &compressedBytes, const size_t bufferBytes, const char *uncompressedBuffer, const size_t uncompressedBytes)
Compress into the supplied buffer.
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
bool isGroup(const AttributeArray &array)
Definition: AttributeGroup.h:92
virtual bool compact()=0
Compact the existing array to become uniform if all values are identical.
Attribute Array storage templated on type and compression codec.
void setStreamingMode(PointDataTreeT &tree, bool on=true)
Toggle the streaming mode on all attributes in the tree to collapse the attributes after deconstructi...
Definition: PointDataGrid.h:1584
ChildOffIter beginChildOff()
Definition: PointDataGrid.h:733
Int32 y() const
Definition: Coord.h:155
T ValueType
Definition: PointDataGrid.h:259
ValueOffCIter cbeginValueOff() const
Definition: PointDataGrid.h:711
void appendAttribute(PointDataTree &tree, const Name &name, const NamePair &type, const Index strideOrTotalSize=1, const bool constantStride=true, Metadata::Ptr metaDefaultValue=Metadata::Ptr(), const bool hidden=false, const bool transient=false)
Appends a new attribute to the VDB tree (this method does not require a templated AttributeType) ...
Definition: PointAttribute.h:463
void addLeafAndCache(PointDataLeafNode *, AccessorT &)
Definition: PointDataGrid.h:455
typename BaseLeaf::ValueOff ValueOff
Definition: PointDataGrid.h:597
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:94
std::shared_ptr< PagedOutputStream > Ptr
Definition: StreamCompression.h:265
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
void modifyValue(Index, const ModifyOp &)
Definition: PointDataGrid.h:554
typename BaseLeaf::template DenseIter< PointDataLeafNode, ValueType, ChildAll > ChildAllIter
Definition: PointDataGrid.h:674
ValueOnCIter endValueOn() const
Definition: PointDataGrid.h:719
void setValueOnly(Index, const ValueType &)
Definition: PointDataGrid.h:534
const PointDataLeafNode * probeLeaf(const Coord &) const
Return a const pointer to this node.
Definition: PointDataGrid.h:483
void setActiveState(const Coord &xyz, bool on)
Definition: PointDataGrid.h:530
virtual void loadData() const =0
Ensures all data is in-core.
void setValueOn(Index offset)
Definition: PointDataGrid.h:543
typename BaseLeaf::ChildOff ChildOff
Definition: PointDataGrid.h:606
PointDataLeafNode * probeLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Definition: PointDataGrid.h:473
void resetBackground(const ValueType &, const ValueType &newBackground)
Definition: PointDataGrid.h:585
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:313
virtual void readPagedBuffers(compression::PagedInputStream &)=0
Read attribute buffers from a paged stream.
void resetDescriptor(const Descriptor::Ptr &replacement)
Replace the descriptor with a new one The new Descriptor must exactly match the old one...
Definition: PointDataGrid.h:858
PointDataLeafNode(const PointDataLeafNode &other, const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Definition: PointDataGrid.h:300
const PointDataLeafNode * probeLeafAndCache(const Coord &, AccessorT &) const
Return a const pointer to this node.
Definition: PointDataGrid.h:482
Base class for storing attribute data.
Definition: AttributeArray.h:118
typename BaseLeaf::ChildOn ChildOn
Definition: PointDataGrid.h:605
Convenience wrappers to using Blosc and reading and writing of Paged data.
Templated block class to hold specific data types and a fixed number of values determined by Log2Dim...
Definition: LeafNode.h:61
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
Definition: StreamCompression.h:262
void signedFloodFill(const ValueType &)
Definition: PointDataGrid.h:589
Index64 memUsage() const
Definition: PointDataGrid.h:1506
Definition: AttributeGroup.h:101
void setValueOn(const Coord &xyz)
Definition: PointDataGrid.h:542
void setActiveState(Index offset, bool on)
Definition: PointDataGrid.h:531
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Leaf nodes have no children, so their child iterators have no get/set accessors.
Definition: LeafNode.h:268
ValueAllCIter cbeginValueAll() const
Definition: PointDataGrid.h:714
Definition: Exceptions.h:87
ValueOffIter beginValueOff()
Definition: PointDataGrid.h:713
typename BaseLeaf::template DenseIter< const PointDataLeafNode, const ValueType, ChildAll > ChildAllCIter
Definition: PointDataGrid.h:676
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:62
std::vector< ValueType > IndexArray
Definition: PointDataGrid.h:261
void addLeaf(PointDataLeafNode *)
Definition: PointDataGrid.h:453
void negate()
Definition: PointDataGrid.h:592
PointDataLeafNode(PartialCreate, const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Definition: PointDataGrid.h:329
ChildAllCIter cendChildAll() const
Definition: PointDataGrid.h:744
ValueOffCIter endValueOff() const
Definition: PointDataGrid.h:722
void setValueOnly(const Coord &, const ValueType &)
Definition: PointDataGrid.h:533
Base class for tree-traversal iterators over all leaf nodes (but not leaf voxels) ...
Definition: TreeIterator.h:1228
ChildAllCIter beginChildAll() const
Definition: PointDataGrid.h:735
typename BaseLeaf::template ValueIter< MaskOffIterator, const PointDataLeafNode, const ValueType, ValueOff > ValueOffCIter
Definition: PointDataGrid.h:660
typename BaseLeaf::template ChildIter< MaskOffIterator, const PointDataLeafNode, ChildOff > ChildOffCIter
Definition: PointDataGrid.h:672
ValueAllIter beginValueAll()
Definition: PointDataGrid.h:716
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
Definition: IndexIterator.h:144
OPENVDB_DEPRECATED void initialize()
typename BaseLeaf::template ValueIter< MaskOnIterator, const PointDataLeafNode, const ValueType, ValueOn > ValueOnCIter
Definition: PointDataGrid.h:656
AttributeSet::Descriptor::Ptr makeDescriptorUnique(PointDataTreeT &tree)
Deep copy the descriptor across all leaf nodes.
Definition: PointDataGrid.h:1567
void compactAttributes(PointDataTree &tree)
Compact attributes in a VDB tree (if possible).
Definition: PointAttribute.h:750
const Coord & max() const
Definition: Coord.h:340
ValueOnCIter beginValueOn() const
Definition: PointDataGrid.h:709
static CoordBBox inf()
Return an "infinite" bounding box, as defined by the Coord value range.
Definition: Coord.h:337
Definition: NodeMasks.h:239
Definition: Exceptions.h:39
ValueOffIter endValueOff()
Definition: PointDataGrid.h:723
typename BaseLeaf::template ChildIter< MaskOffIterator, PointDataLeafNode, ChildOff > ChildOffIter
Definition: PointDataGrid.h:670
void setValueOff(Index offset)
Definition: PointDataGrid.h:537
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
Definition: Platform.h:129
ChildOffCIter endChildOff() const
Definition: PointDataGrid.h:742
Typed class for storing attribute data.
Definition: AttributeArray.h:437
void setValueOn(const Coord &, const ValueType &)
Definition: PointDataGrid.h:545
typename NodeMaskType::OffIterator MaskOffIterator
Definition: PointDataGrid.h:610
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:62
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
Definition: StreamCompression.h:225
const boost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
typename BaseLeaf::ValueOn ValueOn
Definition: PointDataGrid.h:596
typename BaseLeaf::template ValueIter< MaskOffIterator, PointDataLeafNode, const ValueType, ValueOff > ValueOffIter
Definition: PointDataGrid.h:658
SharedPtr< StreamMetadata > Ptr
Definition: io.h:59
void renameAttributes(PointDataTree &tree, const std::vector< Name > &oldNames, const std::vector< Name > &newNames)
Rename attributes in a VDB tree.
Definition: PointAttribute.h:691
Definition: NodeMasks.h:270
ValueOnIter endValueOn()
Definition: PointDataGrid.h:720
typename BaseLeaf::template ValueIter< MaskOnIterator, PointDataLeafNode, const ValueType, ValueOn > ValueOnIter
Definition: PointDataGrid.h:654
PointDataLeafNode(const Coord &coords, const T &value=zeroVal< T >(), bool active=false)
Construct using supplied origin, value and active status.
Definition: PointDataGrid.h:294
void setValueOff(const Coord &, const ValueType &)
Definition: PointDataGrid.h:539
ValueOffCIter cendValueOff() const
Definition: PointDataGrid.h:721
Definition: Exceptions.h:92
void readCompressedValues(std::istream &is, PointDataIndex32 *destBuf, Index destCount, const util::NodeMask< 3 > &, bool)
openvdb::io::readCompressedValues specialized on PointDataIndex32 arrays to ignore the value mask...
Definition: PointDataGrid.h:68
void setOutputStream(std::ostream &os)
Definition: StreamCompression.h:277
static Index size()
Return the total number of voxels represented by this LeafNode.
Definition: LeafNode.h:148
void setInputStream(std::istream &is)
Definition: StreamCompression.h:240
std::shared_ptr< AttributeArray > Ptr
Definition: AttributeArray.h:142
PointDataLeafNode * touchLeafAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Definition: PointDataGrid.h:461
typename BaseLeaf::template ChildIter< MaskOnIterator, const PointDataLeafNode, ChildOn > ChildOnCIter
Definition: PointDataGrid.h:668
Definition: TreeIterator.h:106
Index64 pointCount(const PointDataTreeT &tree, const bool inCoreOnly=false)
Total points in the PointDataTree.
Definition: PointCount.h:198
uint64_t Index64
Definition: Types.h:56
typename BaseLeaf::ChildAll ChildAll
Definition: PointDataGrid.h:607
Definition: InternalNode.h:64
ChildAllCIter endChildAll() const
Definition: PointDataGrid.h:745
#define OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
Definition: Platform.h:130
void modifyValue(const Coord &, const ModifyOp &)
Definition: PointDataGrid.h:557
Definition: Exceptions.h:85
std::string Name
Definition: Name.h:44
Definition: NodeMasks.h:208
Int32 x() const
Definition: Coord.h:154
ChildOffCIter beginChildOff() const
Definition: PointDataGrid.h:732
A forward iterator over array indices in a single voxel.
Definition: IndexIterator.h:72
void signedFloodFill(const ValueType &, const ValueType &)
Definition: PointDataGrid.h:590
bool operator!=(const PointDataLeafNode &other) const
Definition: PointDataGrid.h:451
Definition: PointDataGrid.h:192
typename BaseLeaf::template ValueIter< MaskDenseIterator, const PointDataLeafNode, const ValueType, ValueAll > ValueAllCIter
Definition: PointDataGrid.h:664
ChildOnCIter cbeginChildOn() const
Definition: PointDataGrid.h:728
void dropAttributes(PointDataTree &tree, const std::vector< size_t > &indices)
Drops attributes from the VDB tree.
Definition: PointAttribute.h:604
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only reading size data.
Definition: StreamCompression.h:235
Definition: Tree.h:205
Index filtering on group membership.
Definition: AttributeGroup.h:157
void setValueOff(const Coord &xyz)
Definition: PointDataGrid.h:536
Definition: Exceptions.h:84
Attribute array storage for string data using Descriptor Metadata.
std::pair< ValueType, ValueType > ValueTypePair
Definition: PointDataGrid.h:260
Bit mask for the internal and leaf nodes of VDB. This is a 64-bit implementation. ...
Definition: NodeMasks.h:307
ChildOnCIter endChildOn() const
Definition: PointDataGrid.h:739
void setValueOnlyAndCache(const Coord &, const ValueType &, AccessorT &)
Definition: PointDataGrid.h:570
OPENVDB_API SharedPtr< StreamMetadata > getStreamMetadataPtr(std::ios_base &)
Return a shared pointer to an object that stores metadata (file format, compression scheme...
OPENVDB_API void bloscDecompress(char *uncompressedBuffer, const size_t expectedBytes, const size_t bufferBytes, const char *compressedBuffer)
Decompress into the supplied buffer. Will throw if decompression fails or uncompressed buffer has ins...
Descriptor & descriptor()
Return a reference to this attribute set&#39;s descriptor, which might be shared with other sets...
Definition: AttributeSet.h:121
ChildAllIter endChildAll()
Definition: PointDataGrid.h:746
typename BaseLeaf::template ChildIter< MaskOnIterator, PointDataLeafNode, ChildOn > ChildOnIter
Definition: PointDataGrid.h:666
Definition: PointIndexGrid.h:79
ChildAllCIter cbeginChildAll() const
Definition: PointDataGrid.h:734
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
Tag dispatch class that distinguishes constructors during file input.
Definition: Types.h:505
void setValueOff(Index, const ValueType &)
Definition: PointDataGrid.h:540
const NodeT * probeConstNodeAndCache(const Coord &, AccessorT &) const
Return a const pointer to this node.
Definition: PointDataGrid.h:485
ChildAllIter beginChildAll()
Definition: PointDataGrid.h:736
ValueAllCIter beginValueAll() const
Definition: PointDataGrid.h:715
void flush()
Manually flushes the current page to disk if non-zero.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Definition: RootNode.h:75
const Coord & min() const
Definition: Coord.h:339
int32_t Int32
Definition: Types.h:59
void writeCompressedValues(std::ostream &os, PointDataIndex32 *srcBuf, Index srcCount, const util::NodeMask< 3 > &, const util::NodeMask< 3 > &, bool)
openvdb::io::writeCompressedValues specialized on PointDataIndex32 arrays to ignore the value mask...
Definition: PointDataGrid.h:128
Index32 Index
Definition: Types.h:57
void assertNonmodifiable()
Definition: PointDataGrid.h:519
Integer wrapper, required to distinguish PointIndexGrid and PointDataGrid from Int32Grid and Int64Gri...
Definition: Types.h:173
std::shared_ptr< PagedInputStream > Ptr
Definition: StreamCompression.h:228
ValueOnIter beginValueOn()
Definition: PointDataGrid.h:710
NodeT * probeNodeAndCache(const Coord &, AccessorT &)
Return a pointer to this node.
Definition: PointDataGrid.h:464
AttributeSet::Descriptor Descriptor
Definition: PointDataGrid.h:263
PointDataLeafNode(const tree::LeafNode< ValueType, Log2Dim > &other, const T &, const T &, TopologyCopy)
Definition: PointDataGrid.h:324
ValueAllCIter endValueAll() const
Definition: PointDataGrid.h:725
std::map< std::string, boost::any > AuxDataMap
Definition: io.h:113
PointDataLeafNode()
Default constructor.
Definition: PointDataGrid.h:282
ValueOnCIter cbeginValueOn() const
Definition: PointDataGrid.h:708
ChildOnIter endChildOn()
Definition: PointDataGrid.h:740
ChildOffCIter cendChildOff() const
Definition: PointDataGrid.h:741
typename NodeMaskType::OnIterator MaskOnIterator
Definition: PointDataGrid.h:609
ChildOffIter endChildOff()
Definition: PointDataGrid.h:743
Definition: AttributeGroup.h:128
typename BaseLeaf::template ValueIter< MaskDenseIterator, PointDataLeafNode, const ValueType, ValueAll > ValueAllIter
Definition: PointDataGrid.h:662
ValueAllIter endValueAll()
Definition: PointDataGrid.h:726
void fill(const ValueType &value)
Definition: PointDataGrid.h:566
Base class for iterators over internal and leaf nodes.
Definition: Iterator.h:58
Set of Attribute Arrays which tracks metadata about each array.
const PointDataLeafNode * probeConstLeafAndCache(const Coord &, AccessorT &) const
Return a const pointer to this node.
Definition: PointDataGrid.h:480
void assertNonModifiableUnlessZero(const ValueType &value)
Definition: PointDataGrid.h:526
void clip(const CoordBBox &, const ValueType &value)
Definition: PointDataGrid.h:563
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only writing size data.
Definition: StreamCompression.h:272
OPENVDB_DEPRECATED void uninitialize()
typename BaseLeaf::ValueAll ValueAll
Definition: PointDataGrid.h:598
const AttributeSet & attributeSet() const
Retrieve the attribute set.
Definition: PointDataGrid.h:338