HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_RawIndexField.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SIM_RawendexField.h ( SIM Library, C++)
7  *
8  * COMMENTS:
9  * An RawIndexField tracks a per-voxel index so one can
10  * convert a raw field to a linear coordinate system
11  * and back again.
12  */
13 
14 #ifndef __SIM_RawIndexField__
15 #define __SIM_RawIndexField__
16 
17 #include "SIM_API.h"
18 
19 #include <UT/UT_VoxelArray.h>
20 
22 
23 #include "SIM_RawField.h"
24 
25 /// Voxel boxes are used to define voxel groups
27 {
28  SIM_VoxelBox();
29  SIM_VoxelBox(
30  const int xMin, const int yMin, const int zMin,
31  const int xEnd, const int yEnd, const int zEnd
32  );
33 
34  bool contains(const int x, const int y, const int z) const;
35 
36  // Represent all voxels v with begin[d] <= v[d] < end[d] for d < 3.
37  int begin[3];
38  int end[3];
39 };
40 
42 {
43 public:
45  typedef SIM_VoxelBox Box;
47 
49  virtual ~SIM_RawIndexField();
50 
51  /// Copy constructor:
53 
54  /// Assigment operator:
55  const SIM_RawIndexField &operator=(const SIM_RawIndexField &src);
56 
57  /// Initializes the field.
58  /// The resolution given is in terms of voxels, the actual dimensions
59  /// of this field may be slightly different due to the sampling
60  /// choice.
61  void init(SIM_FieldSample sample,
62  const UT_Vector3 &orig, const UT_Vector3 &size,
63  int xres, int yres, int zres);
64  void init(SIM_FieldSample sample,
65  const UT_Vector3 &orig, const UT_Vector3 &size,
66  int xres, int yres, int zres,
67  const UT_Vector3 &voxelsize);
68 
69  /// Initialize this to be the same dimension and sampling
70  /// patern as the given field.
71  void match(const SIM_RawField &src);
72  void match(const SIM_RawIndexField &src);
73 
74  /// Sets this field to a constant value
75  void makeConstant(exint cval);
76 
77  /// Convert indices to world coordinates and vice-versa. Note this uses
78  /// this field's indices which change depending on sampling.
79  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
80  bool indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
81  bool indexToPos(UT_Vector3I index, UT_Vector3 &pos) const;
82  UT_Vector3 indexToPos(UT_Vector3I index) const;
83 
84  /// Converts a worldspace position into an integer index.
85  bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
86  UT_Vector3I posToIndex(UT_Vector3 pos) const;
87 
88 
89  /// Returns true if the given field and this one match in terms
90  /// of number of voxels and bounding box size.
91  /// This means the voxel cells match - not necessarily the sample
92  /// points!
93  bool isMatching(const SIM_RawIndexField *field) const;
94 
95  /// Returns true if the two fields are precisely aligned. This
96  /// means that samples are matched so a given integer index
97  /// into either field would give the same result.
98  bool isAligned(const SIM_RawIndexField *field) const;
99  bool isAligned(const SIM_RawField *field) const;
100 
101  /// Returns true if two fields have voxels aligned.
102  /// They do not have to be of the same resolution or share origin.
103  /// However, using the `offset` allows to access this field with index
104  /// of the other field.
105  /// i.e. field->indexToPos(index) == this->indexToPos(index + offset)
106  bool isColocated(const SIM_RawField *field, UT_Vector3I &offset) const;
107  bool isColocated(const SIM_RawIndexField *field, UT_Vector3I &offset) const;
108 
109  exint getMemoryUsage() const;
110 
111  /// Returns the resolution of the voxel grid that we are sampling.
112  /// This is a count of voxels, so may differ for our different
113  /// sampling methods.
114  UT_Vector3I getVoxelRes() const;
115  void getVoxelRes(int &xres, int &yres, int &zres) const;
116 
117  /// Returns the actual number of samples in each resolution.
118  /// Preferred over field()->getXRes() as it doesn't require a
119  /// copy of the CE fields.
120  int getXRes() const { return myField->getXRes(); }
121  int getYRes() const { return myField->getYRes(); }
122  int getZRes() const { return myField->getZRes(); }
123 
124  /// Consistently compute a world origin for what world space 0,0,0
125  /// would map to. A bit tricky as we want to avoid round off
126  /// if we line up to 0.5...
127  /// This is not necessarily 0,0,0.
128  void getWorldOrigin(int &origx, int &origy, int &origz) const;
129 
130  const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
131  void setVoxelSize(const UT_Vector3 &voxelsize)
132  { myVoxelSize = voxelsize;
133  myVoxelDiameter = voxelsize.length(); }
134  fpreal getVoxelDiameter() const { return myVoxelDiameter; }
135 
136  UT_VoxelBorderType getBorder() const { return myField->getBorder(); }
137  exint getBorderValue() const { return myField->getBorderValue(); }
139  { myField->setBorder(border, bval); }
140 
141  /// Returns true if the given x, y, z values lie inside the valid index.
142  bool isValidIndex(int x, int y, int z) const
143  {
144  return field()->isValidIndex(x, y, z);
145  }
146 
147  /// Returns the set of samples in *this* field which correspond
148  /// to the given location & sampling pattern.
149  /// ix, iy, and iz should be size 8.
150  /// If you want the deltas for the sampling pattern, call with
151  /// x, y, z zero and clamp to false.
152  void getSamplePattern(SIM_FieldSample sample,
153  int x, int y, int z,
154  int &numsample,
155  int *ix, int *iy, int *iz,
156  bool clamp) const;
157 
158  /// Builds from a surface & collision field.
159  /// -1 if inside collision, -2 if not in collision and not in
160  /// surface, otherwise a unique number.
161  /// Returns maximum index (which you can also get from getMaxIndex)
162  exint buildIndex(const SIM_RawField *surface,
163  const SIM_RawField *collision);
164 
165  // Partitions the voxels into sets.
166  exint buildPartitionedIndex(const SIM_RawField *surface,
167  const SIM_RawField *collision);
168 
169  // Each voxel is an index of where we should copy our values
170  // to perform a SAME boundary collision. this should already
171  // be inited to the desired resolution.
172  // -1 for voxels that don't need collision lookups, otherwise
173  // it is x+(y+z*yres)*xres
174  // Will only write to non- -1 voxels, so call constant(-1) first.
175  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
176  buildCollisionLookup,
177  const SIM_RawField *, collision)
178  void buildCollisionLookupPartial(const SIM_RawField *collision,
180 
181  /// Computes the connected components of the given field.
182  /// Anything with a value < 0 will be considered "inside" and
183  /// connected to each other. Voxels with a value >= 0 will be
184  /// flagged as being in component -1.
185  /// The maxIndex will store the number of connected components.
186  exint computeConnectedComponents(const SIM_RawField &surface);
187 
188  /// Computes the connected components according to the given index
189  /// values. Areas of -1, -2, and >=0 will be consdiered three different
190  /// material types and connectivity computed respectively.
191  exint computeConnectedComponents(const SIM_RawIndexField &idx);
192 
193  exint computeConnectedComponentsWeighted(const SIM_RawIndexField &idx,
195  const SIM_RawIndexField *sliceindex = 0,
196  int thisslice = -1);
197 
198  /// Computes connectivity of the -2 and >= 0 material types.
199  void computeMetaConnected(UT_IntArray &metagroups,
201 
202  /// Returns true if this should be multithreaded.
203  bool shouldMultiThread() const
204  {
205  return field()->numTiles() > 1;
206  }
207 
208  exint operator()(int x, int y, int z) const
209  {
210  return (*field())(x, y, z);
211  }
213  {
214  return (*field())(vit.x(), vit.y(), vit.z());
215  }
216 
217  exint getValue(const UT_Vector3 &pos) const;
218 
219  const UT_VoxelArrayI *field() const { return myField; }
220  UT_VoxelArrayI *fieldNC() const { return myField; }
221 
222  exint maxIndex() const { return myMaxIndex; }
223 
224  const UT_Vector3 &getOrig() const { return myOrig; }
225  const UT_Vector3 &getSize() const { return mySize; }
226  const UT_Vector3 &getBBoxOrig() const { return myBBoxOrig; }
227  const UT_Vector3 &getBBoxSize() const { return myBBoxSize; }
228 
229  SIM_FieldSample getSample() const { return mySample; }
230 
231  void extrapolateClosestPoints(const SIM_RawIndexField *altclosept,
232  const GU_Detail *gdp,
233  const openvdb::tools::PointIndexGrid *ptgridvdb,
234  fpreal uniformradius,
235  fpreal bandwidth,
236  bool rebuildsdf,
237  SIM_RawField *dest = NULL,
238  const SIM_RawField::sim_particleToFieldParms *parms = NULL);
239 
240 protected:
241 
242  /// Given a set of connectivity classes, collapse into the minimal
243  /// set and renumber from 0. myMaxIndex will be updated with the
244  /// resulting maximum & the number of components returned.
245  exint collapseClassIndices();
246 
247  /// Determines if two indices should be connected using our empty
248  /// cell merge rule.
249  bool shouldConnectIndices(exint idx1, exint idx2) const;
250 
251  THREADED_METHOD3(SIM_RawIndexField, shouldMultiThread(),
252  initConnectedComponents,
253  const SIM_RawIndexField &, idx,
254  const SIM_RawIndexField *, sliceindex,
255  int, thisslice);
256  void initConnectedComponentsPartial(const SIM_RawIndexField &idx,
257  const SIM_RawIndexField *sliceindex,
258  int thisslice,
259  const UT_JobInfo &info);
260 
261  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
262  applyLookup,
263  const UT_VoxelArrayI &, lut);
264  void applyLookupPartial(const UT_VoxelArrayI &lut,
265  const UT_JobInfo &info);
266 
270 
271  // This is the size and offset which converts our UT_VoxelArray into
272  // world coordinates.
274 
275  // This is our actual official size.
276  UT_Vector3 myBBoxOrig, myBBoxSize;
277 
278  // Cached metrics.
281 
282  // Find ranges of indices for valid voxels
283  void findRange
284  (
285  const SIM_RawField* surface,
286  const SIM_RawField* collision,
287  int begin[3],
288  int end[3]
289  ) const;
290 
291  // Count all valid voxels in a box
292  exint countVoxelsInBox
293  (
294  const SIM_RawField* surface,
295  const SIM_RawField* collision,
296  const Box& box
297  ) const;
298 
299 
300  // Closest point extrapolation functions.
302 
303  static sim_extrapelem indexToElement(const UT_VoxelArrayI &U,
304  int x, int y, int z);
305 
306  static void elementToIndex(const UT_VoxelArrayI &U, sim_extrapelem idx,
307  int &x, int &y, int &z);
308 
309  void computeQueryOffsets(const SIM_RawIndexField *nindex,
310  int nsamples,
311  const int *dx, const int *dy, const int *dz,
312  UT_Vector3Array &queryoffsets,
313  UT_ValArray<fpreal> &radii) const;
314 
316  {
320  const GU_Detail *gdp;
327  };
328 
329  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
330  buildActiveLists,
331  const sim_buildActiveParms &, parms);
332 
333  void buildActiveListsPartial(const sim_buildActiveParms &parms,
334  const UT_JobInfo &info);
335 
336  THREADED_METHOD4(SIM_RawIndexField, tileoccupied.entries() > 10,
337  uncompressActiveTiles,
338  UT_VoxelArrayI &, closept,
339  UT_VoxelArrayI &, newclosept,
340  UT_VoxelArrayF *, dest,
341  const UT_ValArray<bool> &, tileoccupied);
342 
343  void uncompressActiveTilesPartial(UT_VoxelArrayI &closept,
344  UT_VoxelArrayI &newclosept,
345  UT_VoxelArrayF *dest,
346  const UT_ValArray<bool> &tileoccupied,
347  const UT_JobInfo &info);
348 
350  {
351  const GU_Detail *gdp;
362  };
363 
364  THREADED_METHOD1(SIM_RawIndexField, parms.elements->entries() > 50,
365  extrapolateActiveElements,
366  const sim_extrapActiveParms &, parms);
367 
368  void extrapolateActiveElementsPartial(const sim_extrapActiveParms &parms,
369  const UT_JobInfo &info);
370 
371  THREADED_METHOD4(SIM_RawIndexField, elements.entries() > 100,
372  applyExtrapolatedParticleToField,
373  const UT_ValArray<sim_extrapelem> &, elements,
374  const GU_Detail *, gdp,
375  SIM_RawField *, dest,
376  const SIM_RawField::sim_particleToFieldParms &, ptfparms);
377 
378  void applyExtrapolatedParticleToFieldPartial(
380  const GU_Detail *gdp,
381  SIM_RawField *dest,
383  const UT_JobInfo &info);
384 };
385 
386 #endif
387 
const UT_Vector3 & getBBoxOrig() const
int x() const
Retrieve the current location of the iterator.
const UT_ValArray< sim_extrapelem > * elements
GLint GLint GLsizei GLint border
Definition: glcorearb.h:107
const UT_VoxelArrayI * field() const
exint getBorderValue() const
const openvdb::tools::PointIndexGrid * ptgridvdb
UT_Array< int64 > Indices
exint operator()(int x, int y, int z) const
GLenum clamp
Definition: glcorearb.h:1233
exint maxIndex() const
void
Definition: png.h:1083
#define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
const UT_Vector3 & getBBoxSize() const
Voxel boxes are used to define voxel groups.
int64 exint
Definition: SYS_Types.h:125
UT_VoxelBorderType
Definition: UT_VoxelArray.h:67
UT_ValArray< UT_ValArray< sim_extrapelem > > * lists
SYS_FORCE_INLINE MF length() const
const UT_Vector3 & getVoxelSize() const
GLenum src
Definition: glcorearb.h:1792
SIM_FieldSample getSample() const
bool isValidIndex(int x, int y, int z) const
Returns true if the given x, y, z values lie inside the valid index.
#define THREADED_METHOD3(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3)
SIM_FieldSample
Definition: SIM_RawField.h:38
UT_VoxelBorderType getBorder() const
GLint GLenum GLint x
Definition: glcorearb.h:408
GLsizeiptr size
Definition: glcorearb.h:663
UT_VoxelArrayI * myField
SIM_FieldSample mySample
GLuint GLuint end
Definition: glcorearb.h:474
const UT_Vector3 & getSize() const
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
#define THREADED_METHOD4(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4)
bool OIIO_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
void setVoxelSize(const UT_Vector3 &voxelsize)
GLsizei const GLint box[]
Definition: glew.h:11654
Grid< PointIndexTree > PointIndexGrid
Point index grid.
fpreal64 fpreal
Definition: SYS_Types.h:277
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
GLuint index
Definition: glcorearb.h:785
const UT_Vector3 & getOrig() const
GLbyte * weights
Definition: glew.h:7581
#define SIM_API
Definition: SIM_API.h:10
const SIM_RawField::sim_particleToFieldParms * ptfparms
UT_VoxelArrayI * fieldNC() const
GLintptr offset
Definition: glcorearb.h:664
#define const
Definition: zconf.h:214
UT_Array< Box > Boxes
fpreal getVoxelDiameter() const
GLint y
Definition: glcorearb.h:102
void setBorder(UT_VoxelBorderType border, exint bval)
exint getIndex(const UT_VoxelArrayIteratorF &vit) const
UT_ValArray< UT_ValArray< sim_extrapelem > > * newelemlists