1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkDenseArray.h
5 
6 -------------------------------------------------------------------------
7   Copyright 2008 Sandia Corporation.
8   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9   the U.S. Government retains certain rights in this software.
10 -------------------------------------------------------------------------
11 
12   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
13   All rights reserved.
14   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
15 
16      This software is distributed WITHOUT ANY WARRANTY; without even
17      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18      PURPOSE.  See the above copyright notice for more information.
19 
20 =========================================================================*/
21 
22 /**
23  * @class   vtkDenseArray
24  * @brief   Contiguous storage for N-way arrays.
25  *
26  *
27  * vtkDenseArray is a concrete vtkArray implementation that stores values
28  * using a contiguous block of memory.  Values are stored with fortran ordering,
29  * meaning that if you iterated over the memory block, the left-most coordinates
30  * would vary the fastest.
31  *
32  * In addition to the retrieval and update methods provided by vtkTypedArray,
33  * vtkDenseArray provides methods to:
34  *
35  * Fill the entire array with a specific value.
36  *
37  * Retrieve a pointer to the storage memory block.
38  *
39  * @sa
40  * vtkArray, vtkTypedArray, vtkSparseArray
41  *
42  * @par Thanks:
43  * Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
44  */
45 
46 #ifndef vtkDenseArray_h
47 #define vtkDenseArray_h
48 
49 #include "vtkArrayCoordinates.h"
50 #include "vtkObjectFactory.h"
51 #include "vtkTypedArray.h"
52 
53 template <typename T>
54 class vtkDenseArray : public vtkTypedArray<T>
55 {
56 public:
57   static vtkDenseArray<T>* New();
58   vtkTemplateTypeMacro(vtkDenseArray<T>, vtkTypedArray<T>);
59   void PrintSelf(ostream& os, vtkIndent indent) override;
60 
61   typedef typename vtkArray::CoordinateT CoordinateT;
62   typedef typename vtkArray::DimensionT DimensionT;
63   typedef typename vtkArray::SizeT SizeT;
64 
65   // vtkArray API
66   bool IsDense() override;
67   const vtkArrayExtents& GetExtents() override;
68   SizeT GetNonNullSize() override;
69   void GetCoordinatesN(const SizeT n, vtkArrayCoordinates& coordinates) override;
70   vtkArray* DeepCopy() override;
71 
72   // vtkTypedArray API
73   const T& GetValue(CoordinateT i) override;
74   const T& GetValue(CoordinateT i, CoordinateT j) override;
75   const T& GetValue(CoordinateT i, CoordinateT j, CoordinateT k) override;
76   const T& GetValue(const vtkArrayCoordinates& coordinates) override;
77   const T& GetValueN(const SizeT n) override;
78   void SetValue(CoordinateT i, const T& value) override;
79   void SetValue(CoordinateT i, CoordinateT j, const T& value) override;
80   void SetValue(CoordinateT i, CoordinateT j, CoordinateT k, const T& value) override;
81   void SetValue(const vtkArrayCoordinates& coordinates, const T& value) override;
82   void SetValueN(const SizeT n, const T& value) override;
83 
84   // vtkDenseArray API
85 
86   /**
87    * Strategy object that contains a block of memory to be used by vtkDenseArray
88    * for value storage.  The MemoryBlock object is responsible for freeing
89    * memory when destroyed.
90    */
91   class MemoryBlock
92   {
93   public:
94     virtual ~MemoryBlock();
95     ///@{
96     /**
97      * Returns a pointer to the block of memory to be used for storage.
98      */
99     virtual T* GetAddress() = 0;
100     ///@}
101   };
102 
103   ///@{
104   /**
105    * MemoryBlock implementation that manages internally-allocated memory using
106    * new[] and delete[].  Note: HeapMemoryBlock is the default used by vtkDenseArray
107    * for its "normal" internal memory allocation.
108    */
109   class HeapMemoryBlock : public MemoryBlock
110   {
111   public:
112     HeapMemoryBlock(const vtkArrayExtents& extents);
113     ~HeapMemoryBlock() override;
114     T* GetAddress() override;
115     ///@}
116 
117   private:
118     T* Storage;
119   };
120 
121   ///@{
122   /**
123    * MemoryBlock implementation that manages a static (will not be freed) memory block.
124    */
125   class StaticMemoryBlock : public MemoryBlock
126   {
127   public:
128     StaticMemoryBlock(T* const storage);
129     T* GetAddress() override;
130     ///@}
131 
132   private:
133     T* Storage;
134   };
135 
136   /**
137    * Initializes the array to use an externally-allocated memory block.  The supplied
138    * MemoryBlock must be large enough to store extents.GetSize() values.  The contents of
139    * the memory must be stored contiguously with fortran ordering,
140 
141    * Dimension-labels are undefined after calling ExternalStorage() - you should
142    * initialize them accordingly.
143 
144    * The array will use the supplied memory for storage until the array goes out of
145    * scope, is configured to use a different memory block by calling ExternalStorage()
146    * again, or is configured to use internally-allocated memory by calling Resize().
147 
148    * Note that the array will delete the supplied memory block when it is no longer in use.
149    * caller's responsibility to ensure that the memory does not go out-of-scope until
150    * the array has been destroyed or is no longer using it.
151    */
152   void ExternalStorage(const vtkArrayExtents& extents, MemoryBlock* storage);
153 
154   /**
155    * Fills every element in the array with the given value.
156    */
157   void Fill(const T& value);
158 
159   /**
160    * Returns a value by-reference, which is useful for performance and code-clarity.
161    */
162   T& operator[](const vtkArrayCoordinates& coordinates);
163 
164   /**
165    * Returns a read-only reference to the underlying storage.  Values are stored
166    * contiguously with fortran ordering.
167    */
168   const T* GetStorage() const;
169 
170   /**
171    * Returns a mutable reference to the underlying storage.  Values are stored
172    * contiguously with fortran ordering.  Use at your own risk!
173    */
174   T* GetStorage();
175 
176 protected:
177   vtkDenseArray();
178   ~vtkDenseArray() override;
179 
180 private:
181   vtkDenseArray(const vtkDenseArray&) = delete;
182   void operator=(const vtkDenseArray&) = delete;
183 
184   void InternalResize(const vtkArrayExtents& extents) override;
185   void InternalSetDimensionLabel(DimensionT i, const vtkStdString& label) override;
186   vtkStdString InternalGetDimensionLabel(DimensionT i) override;
187   inline vtkIdType MapCoordinates(CoordinateT i);
188   inline vtkIdType MapCoordinates(CoordinateT i, CoordinateT j);
189   inline vtkIdType MapCoordinates(CoordinateT i, CoordinateT j, CoordinateT k);
190   inline vtkIdType MapCoordinates(const vtkArrayCoordinates& coordinates);
191 
192   void Reconfigure(const vtkArrayExtents& extents, MemoryBlock* storage);
193 
194   typedef vtkDenseArray<T> ThisT;
195 
196   /**
197    * Stores the current array extents (its size along each dimension)
198    */
199   vtkArrayExtents Extents;
200 
201   /**
202    * Stores labels for each array dimension
203    */
204   std::vector<vtkStdString> DimensionLabels;
205 
206   /**
207    * Manages array value memory storage.
208    */
209   MemoryBlock* Storage;
210 
211   ///@{
212   /**
213    * Stores array values using a contiguous range of memory
214    * with constant-time value lookup.
215    */
216   T* Begin;
217   T* End;
218   ///@}
219 
220   /**
221    * Stores the offset along each array dimension (used for fast lookups).
222    */
223   std::vector<vtkIdType> Offsets;
224   ///@{
225   /**
226    * Stores the stride along each array dimension (used for fast lookups).
227    */
228   std::vector<vtkIdType> Strides;
229   ///@}
230 };
231 
232 #include "vtkDenseArray.txx"
233 
234 #endif
235 
236 // VTK-HeaderTest-Exclude: vtkDenseArray.h
237