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  /// Initializes the field.
69  /// Will gain ownership of the given voxel array.
70  void init(SIM_FieldSample sample,
71  const UT_Vector3 &orig, const UT_Vector3 &size,
72  UT_VoxelArrayI *voxels,
73  const UT_Vector3 &voxelsize);
74 
75  /// Initialize this to be the same dimension and sampling
76  /// patern as the given field.
77  void match(const SIM_RawField &src);
78  void match(const SIM_RawIndexField &src);
79 
80  /// Sets this field to a constant value
81  void makeConstant(exint cval);
82 
83  /// Convert indices to world coordinates and vice-versa. Note this uses
84  /// this field's indices which change depending on sampling.
85  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
86  bool indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
87  bool indexToPos(UT_Vector3I index, UT_Vector3 &pos) const;
88  UT_Vector3 indexToPos(UT_Vector3I index) const;
89 
90  /// Converts a worldspace position into an integer index.
91  bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
92  UT_Vector3I posToIndex(UT_Vector3 pos) const;
93 
94 
95  /// Returns true if the given field and this one match in terms
96  /// of number of voxels and bounding box size.
97  /// This means the voxel cells match - not necessarily the sample
98  /// points!
99  bool isMatching(const SIM_RawIndexField *field) const;
100  bool isMatching(const SIM_RawField *field) const;
101 
102  /// Returns true if the two fields are precisely aligned. This
103  /// means that samples are matched so a given integer index
104  /// into either field would give the same result.
105  bool isAligned(const SIM_RawIndexField *field) const;
106  bool isAligned(const SIM_RawField *field) const;
107 
108  /// Returns true if two fields have voxels aligned.
109  /// They do not have to be of the same resolution or share origin.
110  /// However, using the `offset` allows to access this field with index
111  /// of the other field.
112  /// i.e. field->indexToPos(index) == this->indexToPos(index + offset)
113  bool isColocated(const SIM_RawField *field, UT_Vector3I &offset) const;
114  bool isColocated(const SIM_RawIndexField *field, UT_Vector3I &offset) const;
115 
116  /// Steals the voxel array, leaving this pointing to a 0 constant array.
117  UT_VoxelArrayI *steal();
118 
119  exint getMemoryUsage() const;
120 
121  /// Returns the resolution of the voxel grid that we are sampling.
122  /// This is a count of voxels, so may differ for our different
123  /// sampling methods.
124  UT_Vector3I getVoxelRes() const;
125  void getVoxelRes(int &xres, int &yres, int &zres) const;
126 
127  /// Returns the actual number of samples in each resolution.
128  /// Preferred over field()->getXRes() as it doesn't require a
129  /// copy of the CE fields.
130  int getXRes() const { return myField->getXRes(); }
131  int getYRes() const { return myField->getYRes(); }
132  int getZRes() const { return myField->getZRes(); }
133 
134  /// Consistently compute a world origin for what world space 0,0,0
135  /// would map to. A bit tricky as we want to avoid round off
136  /// if we line up to 0.5...
137  /// This is not necessarily 0,0,0.
138  void getWorldOrigin(int &origx, int &origy, int &origz) const;
139 
140  const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
141  void setVoxelSize(const UT_Vector3 &voxelsize)
142  { myVoxelSize = voxelsize;
143  myVoxelDiameter = voxelsize.length(); }
144  fpreal getVoxelDiameter() const { return myVoxelDiameter; }
145 
146  UT_VoxelBorderType getBorder() const { return myField->getBorder(); }
147  exint getBorderValue() const { return myField->getBorderValue(); }
149  { myField->setBorder(border, bval); }
150 
151  /// Returns true if the given x, y, z values lie inside the valid index.
152  bool isValidIndex(int x, int y, int z) const
153  {
154  return field()->isValidIndex(x, y, z);
155  }
156 
157  /// Returns the set of samples in *this* field which correspond
158  /// to the given location & sampling pattern.
159  /// ix, iy, and iz should be size 8.
160  /// If you want the deltas for the sampling pattern, call with
161  /// x, y, z zero and clamp to false.
162  void getSamplePattern(SIM_FieldSample sample,
163  int x, int y, int z,
164  int &numsample,
165  int *ix, int *iy, int *iz,
166  bool clamp) const;
167 
168  /// Builds from a surface & collision field.
169  /// -1 if inside collision, -2 if not in collision and not in
170  /// surface, otherwise a unique number.
171  /// Returns maximum index (which you can also get from getMaxIndex)
172  exint buildIndex(const SIM_RawField *surface,
173  const SIM_RawField *collision);
174 
175  // Partitions the voxels into sets.
176  exint buildPartitionedIndex(const SIM_RawField *surface,
177  const SIM_RawField *collision);
178 
179  // Each voxel is an index of where we should copy our values
180  // to perform a SAME boundary collision. this should already
181  // be inited to the desired resolution.
182  // -1 for voxels that don't need collision lookups, otherwise
183  // it is x+(y+z*yres)*xres
184  // Will only write to non- -1 voxels, so call constant(-1) first.
185  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
186  buildCollisionLookup,
187  const SIM_RawField *, collision)
188  void buildCollisionLookupPartial(const SIM_RawField *collision,
190 
191  /// Computes the connected components of the given field.
192  /// Anything with a value < 0 will be considered "inside" and
193  /// connected to each other. Voxels with a value >= 0 will be
194  /// flagged as being in component -1.
195  /// The maxIndex will store the number of connected components.
196  exint computeConnectedComponents(const SIM_RawField &surface);
197 
198  /// Computes the connected components according to the given index
199  /// values. Areas of -1, -2, and >=0 will be consdiered three different
200  /// material types and connectivity computed respectively.
201  exint computeConnectedComponents(const SIM_RawIndexField &idx);
202 
203  exint computeConnectedComponentsWeighted(const SIM_RawIndexField &idx,
205  const SIM_RawIndexField *sliceindex = 0,
206  int thisslice = -1);
207 
208  /// Computes connectivity of the -2 and >= 0 material types.
209  void computeMetaConnected(UT_IntArray &metagroups,
211 
212  /// Returns true if this should be multithreaded.
213  bool shouldMultiThread() const
214  {
215  return field()->numTiles() > 1;
216  }
217 
218  exint operator()(int x, int y, int z) const
219  {
220  return (*field())(x, y, z);
221  }
223  {
224  return (*field())(vit.x(), vit.y(), vit.z());
225  }
226 
227  exint getValue(const UT_Vector3 &pos) const;
228 
229  const UT_VoxelArrayI *field() const { return myField; }
230  UT_VoxelArrayI *fieldNC() const { return myField; }
231 
232  exint maxIndex() const { return myMaxIndex; }
233 
234  const UT_Vector3 &getOrig() const { return myOrig; }
235  const UT_Vector3 &getSize() const { return mySize; }
236  const UT_Vector3 &getBBoxOrig() const { return myBBoxOrig; }
237  const UT_Vector3 &getBBoxSize() const { return myBBoxSize; }
238 
239  SIM_FieldSample getSample() const { return mySample; }
240 
241  void extrapolateClosestPoints(const SIM_RawIndexField *altclosept,
242  const GU_Detail *gdp,
243  const openvdb::tools::PointIndexGrid *ptgridvdb,
244  fpreal uniformradius,
245  fpreal bandwidth,
246  bool rebuildsdf,
247  SIM_RawField *dest = NULL,
248  const SIM_RawField::sim_particleToFieldParms *parms = NULL);
249 
250 protected:
251 
252  /// Given a set of connectivity classes, collapse into the minimal
253  /// set and renumber from 0. myMaxIndex will be updated with the
254  /// resulting maximum & the number of components returned.
255  exint collapseClassIndices();
256 
257  /// Determines if two indices should be connected using our empty
258  /// cell merge rule.
259  bool shouldConnectIndices(exint idx1, exint idx2) const;
260 
261  THREADED_METHOD3(SIM_RawIndexField, shouldMultiThread(),
262  initConnectedComponents,
263  const SIM_RawIndexField &, idx,
264  const SIM_RawIndexField *, sliceindex,
265  int, thisslice);
266  void initConnectedComponentsPartial(const SIM_RawIndexField &idx,
267  const SIM_RawIndexField *sliceindex,
268  int thisslice,
269  const UT_JobInfo &info);
270 
271  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
272  applyLookup,
273  const UT_VoxelArrayI &, lut);
274  void applyLookupPartial(const UT_VoxelArrayI &lut,
275  const UT_JobInfo &info);
276 
280 
281  // This is the size and offset which converts our UT_VoxelArray into
282  // world coordinates.
284 
285  // This is our actual official size.
286  UT_Vector3 myBBoxOrig, myBBoxSize;
287 
288  // Cached metrics.
291 
292  // Find ranges of indices for valid voxels
293  void findRange
294  (
295  const SIM_RawField* surface,
296  const SIM_RawField* collision,
297  int begin[3],
298  int end[3]
299  ) const;
300 
301  // Count all valid voxels in a box
302  exint countVoxelsInBox
303  (
304  const SIM_RawField* surface,
305  const SIM_RawField* collision,
306  const Box& box
307  ) const;
308 
309 
310  // Closest point extrapolation functions.
312 
313  static sim_extrapelem indexToElement(const UT_VoxelArrayI &U,
314  int x, int y, int z);
315 
316  static void elementToIndex(const UT_VoxelArrayI &U, sim_extrapelem idx,
317  int &x, int &y, int &z);
318 
319  void computeQueryOffsets(const SIM_RawIndexField *nindex,
320  int nsamples,
321  const int *dx, const int *dy, const int *dz,
322  UT_Vector3Array &queryoffsets,
323  UT_ValArray<fpreal> &radii) const;
324 
326  {
330  const GU_Detail *gdp;
337  };
338 
339  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
340  buildActiveLists,
341  const sim_buildActiveParms &, parms);
342 
343  void buildActiveListsPartial(const sim_buildActiveParms &parms,
344  const UT_JobInfo &info);
345 
346  THREADED_METHOD4(SIM_RawIndexField, tileoccupied.entries() > 10,
347  uncompressActiveTiles,
348  UT_VoxelArrayI &, closept,
349  UT_VoxelArrayI &, newclosept,
350  UT_VoxelArrayF *, dest,
351  const UT_ValArray<bool> &, tileoccupied);
352 
353  void uncompressActiveTilesPartial(UT_VoxelArrayI &closept,
354  UT_VoxelArrayI &newclosept,
355  UT_VoxelArrayF *dest,
356  const UT_ValArray<bool> &tileoccupied,
357  const UT_JobInfo &info);
358 
360  {
361  const GU_Detail *gdp;
372  };
373 
374  THREADED_METHOD1(SIM_RawIndexField, parms.elements->entries() > 50,
375  extrapolateActiveElements,
376  const sim_extrapActiveParms &, parms);
377 
378  void extrapolateActiveElementsPartial(const sim_extrapActiveParms &parms,
379  const UT_JobInfo &info);
380 
381  THREADED_METHOD4(SIM_RawIndexField, elements.entries() > 100,
382  applyExtrapolatedParticleToField,
383  const UT_ValArray<sim_extrapelem> &, elements,
384  const GU_Detail *, gdp,
385  SIM_RawField *, dest,
386  const SIM_RawField::sim_particleToFieldParms &, ptfparms);
387 
388  void applyExtrapolatedParticleToFieldPartial(
390  const GU_Detail *gdp,
391  SIM_RawField *dest,
393  const UT_JobInfo &info);
394 };
395 
396 #endif
397 
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:108
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:1234
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
constexpr SYS_FORCE_INLINE T length() const noexcept
Definition: UT_Vector3.h:352
const UT_Vector3 & getVoxelSize() const
GLenum src
Definition: glcorearb.h:1793
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:409
GLsizeiptr size
Definition: glcorearb.h:664
UT_VoxelArrayI * myField
SIM_FieldSample mySample
GLuint GLuint end
Definition: glcorearb.h:475
const UT_Vector3 & getSize() const
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
#define THREADED_METHOD4(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4)
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:786
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:665
#define const
Definition: zconf.h:214
UT_Array< Box > Boxes
bool OIIO_UTIL_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
fpreal getVoxelDiameter() const
GLint y
Definition: glcorearb.h:103
void setBorder(UT_VoxelBorderType border, exint bval)
exint getIndex(const UT_VoxelArrayIteratorF &vit) const
UT_ValArray< UT_ValArray< sim_extrapelem > > * newelemlists
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:450