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 
82  /// Converts a worldspace position into an integer index.
83  bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
84 
85  /// Returns true if the given field and this one match in terms
86  /// of number of voxels and bounding box size.
87  /// This means the voxel cells match - not necessarily the sample
88  /// points!
89  bool isMatching(const SIM_RawIndexField *field) const;
90 
91  /// Returns true if the two fields are precisely aligned. This
92  /// means that samples are matched so a given integer index
93  /// into either field would give the same result.
94  bool isAligned(const SIM_RawIndexField *field) const;
95  bool isAligned(const SIM_RawField *field) const;
96 
97  exint getMemoryUsage() const;
98 
99  /// Returns the resolution of the voxel grid that we are sampling.
100  /// This is a count of voxels, so may differ for our different
101  /// sampling methods.
102  UT_Vector3I getVoxelRes() const;
103  void getVoxelRes(int &xres, int &yres, int &zres) const;
104 
105  /// Returns the actual number of samples in each resolution.
106  /// Preferred over field()->getXRes() as it doesn't require a
107  /// copy of the CE fields.
108  int getXRes() const { return myField->getXRes(); }
109  int getYRes() const { return myField->getYRes(); }
110  int getZRes() const { return myField->getZRes(); }
111 
112  /// Consistently compute a world origin for what world space 0,0,0
113  /// would map to. A bit tricky as we want to avoid round off
114  /// if we line up to 0.5...
115  /// This is not necessarily 0,0,0.
116  void getWorldOrigin(int &origx, int &origy, int &origz) const;
117 
118  const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
119  void setVoxelSize(const UT_Vector3 &voxelsize)
120  { myVoxelSize = voxelsize;
121  myVoxelDiameter = voxelsize.length(); }
122  fpreal getVoxelDiameter() const { return myVoxelDiameter; }
123 
124  UT_VoxelBorderType getBorder() const { return myField->getBorder(); }
125  exint getBorderValue() const { return myField->getBorderValue(); }
127  { myField->setBorder(border, bval); }
128 
129  /// Returns true if the given x, y, z values lie inside the valid index.
130  bool isValidIndex(int x, int y, int z) const
131  {
132  return field()->isValidIndex(x, y, z);
133  }
134 
135  /// Returns the set of samples in *this* field which correspond
136  /// to the given location & sampling pattern.
137  /// ix, iy, and iz should be size 8.
138  /// If you want the deltas for the sampling pattern, call with
139  /// x, y, z zero and clamp to false.
140  void getSamplePattern(SIM_FieldSample sample,
141  int x, int y, int z,
142  int &numsample,
143  int *ix, int *iy, int *iz,
144  bool clamp) const;
145 
146  /// Builds from a surface & collision field.
147  /// -1 if inside collision, -2 if not in collision and not in
148  /// surface, otherwise a unique number.
149  /// Returns maximum index (which you can also get from getMaxIndex)
150  exint buildIndex(const SIM_RawField *surface,
151  const SIM_RawField *collision);
152 
153  // Partitions the voxels into sets.
154  exint buildPartitionedIndex(const SIM_RawField *surface,
155  const SIM_RawField *collision);
156 
157  // Each voxel is an index of where we should copy our values
158  // to perform a SAME boundary collision. this should already
159  // be inited to the desired resolution.
160  // -1 for voxels that don't need collision lookups, otherwise
161  // it is x+(y+z*yres)*xres
162  // Will only write to non- -1 voxels, so call constant(-1) first.
163  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
164  buildCollisionLookup,
165  const SIM_RawField *, collision)
166  void buildCollisionLookupPartial(const SIM_RawField *collision,
168 
169  /// Computes the connected components of the given field.
170  /// Anything with a value < 0 will be considered "inside" and
171  /// connected to each other. Voxels with a value >= 0 will be
172  /// flagged as being in component -1.
173  /// The maxIndex will store the number of connected components.
174  exint computeConnectedComponents(const SIM_RawField &surface);
175 
176  /// Computes the connected components according to the given index
177  /// values. Areas of -1, -2, and >=0 will be consdiered three different
178  /// material types and connectivity computed respectively.
179  exint computeConnectedComponents(const SIM_RawIndexField &idx);
180 
181  exint computeConnectedComponentsWeighted(const SIM_RawIndexField &idx,
183  const SIM_RawIndexField *sliceindex = 0,
184  int thisslice = -1);
185 
186  /// Computes connectivity of the -2 and >= 0 material types.
187  void computeMetaConnected(UT_IntArray &metagroups,
189 
190  /// Returns true if this should be multithreaded.
191  bool shouldMultiThread() const
192  {
193  return field()->numTiles() > 1;
194  }
195 
196  exint operator()(int x, int y, int z) const
197  {
198  return (*field())(x, y, z);
199  }
201  {
202  return (*field())(vit.x(), vit.y(), vit.z());
203  }
204 
205  exint getValue(const UT_Vector3 &pos) const;
206 
207  const UT_VoxelArrayI *field() const { return myField; }
208  UT_VoxelArrayI *fieldNC() const { return myField; }
209 
210  exint maxIndex() const { return myMaxIndex; }
211 
212  const UT_Vector3 &getOrig() const { return myOrig; }
213  const UT_Vector3 &getSize() const { return mySize; }
214  const UT_Vector3 &getBBoxOrig() const { return myBBoxOrig; }
215  const UT_Vector3 &getBBoxSize() const { return myBBoxSize; }
216 
217  SIM_FieldSample getSample() const { return mySample; }
218 
219  void extrapolateClosestPoints(const SIM_RawIndexField *altclosept,
220  const GU_Detail *gdp,
221  const openvdb::tools::PointIndexGrid *ptgridvdb,
222  fpreal uniformradius,
223  fpreal bandwidth,
224  bool rebuildsdf,
225  SIM_RawField *dest = NULL,
226  const SIM_RawField::sim_particleToFieldParms *parms = NULL);
227 
228 protected:
229 
230  /// Given a set of connectivity classes, collapse into the minimal
231  /// set and renumber from 0. myMaxIndex will be updated with the
232  /// resulting maximum & the number of components returned.
233  exint collapseClassIndices();
234 
235  /// Determines if two indices should be connected using our empty
236  /// cell merge rule.
237  bool shouldConnectIndices(exint idx1, exint idx2) const;
238 
239  THREADED_METHOD3(SIM_RawIndexField, shouldMultiThread(),
240  initConnectedComponents,
241  const SIM_RawIndexField &, idx,
242  const SIM_RawIndexField *, sliceindex,
243  int, thisslice);
244  void initConnectedComponentsPartial(const SIM_RawIndexField &idx,
245  const SIM_RawIndexField *sliceindex,
246  int thisslice,
247  const UT_JobInfo &info);
248 
249  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
250  applyLookup,
251  const UT_VoxelArrayI &, lut);
252  void applyLookupPartial(const UT_VoxelArrayI &lut,
253  const UT_JobInfo &info);
254 
258 
259  // This is the size and offset which converts our UT_VoxelArray into
260  // world coordinates.
262 
263  // This is our actual official size.
264  UT_Vector3 myBBoxOrig, myBBoxSize;
265 
266  // Cached metrics.
269 
270  // Find ranges of indices for valid voxels
271  void findRange
272  (
273  const SIM_RawField* surface,
274  const SIM_RawField* collision,
275  int begin[3],
276  int end[3]
277  ) const;
278 
279  // Count all valid voxels in a box
280  exint countVoxelsInBox
281  (
282  const SIM_RawField* surface,
283  const SIM_RawField* collision,
284  const Box& box
285  ) const;
286 
287 
288  // Closest point extrapolation functions.
290 
291  static sim_extrapelem indexToElement(const UT_VoxelArrayI &U,
292  int x, int y, int z);
293 
294  static void elementToIndex(const UT_VoxelArrayI &U, sim_extrapelem idx,
295  int &x, int &y, int &z);
296 
297  void computeQueryOffsets(const SIM_RawIndexField *nindex,
298  int nsamples,
299  const int *dx, const int *dy, const int *dz,
300  UT_Vector3Array &queryoffsets,
301  UT_ValArray<fpreal> &radii) const;
302 
304  {
308  const GU_Detail *gdp;
315  };
316 
317  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
318  buildActiveLists,
319  const sim_buildActiveParms &, parms);
320 
321  void buildActiveListsPartial(const sim_buildActiveParms &parms,
322  const UT_JobInfo &info);
323 
324  THREADED_METHOD4(SIM_RawIndexField, tileoccupied.entries() > 10,
325  uncompressActiveTiles,
326  UT_VoxelArrayI &, closept,
327  UT_VoxelArrayI &, newclosept,
328  UT_VoxelArrayF *, dest,
329  const UT_ValArray<bool> &, tileoccupied);
330 
331  void uncompressActiveTilesPartial(UT_VoxelArrayI &closept,
332  UT_VoxelArrayI &newclosept,
333  UT_VoxelArrayF *dest,
334  const UT_ValArray<bool> &tileoccupied,
335  const UT_JobInfo &info);
336 
338  {
339  const GU_Detail *gdp;
350  };
351 
352  THREADED_METHOD1(SIM_RawIndexField, parms.elements->entries() > 50,
353  extrapolateActiveElements,
354  const sim_extrapActiveParms &, parms);
355 
356  void extrapolateActiveElementsPartial(const sim_extrapActiveParms &parms,
357  const UT_JobInfo &info);
358 
359  THREADED_METHOD4(SIM_RawIndexField, elements.entries() > 100,
360  applyExtrapolatedParticleToField,
361  const UT_ValArray<sim_extrapelem> &, elements,
362  const GU_Detail *, gdp,
363  SIM_RawField *, dest,
364  const SIM_RawField::sim_particleToFieldParms &, ptfparms);
365 
366  void applyExtrapolatedParticleToFieldPartial(
368  const GU_Detail *gdp,
369  SIM_RawField *dest,
371  const UT_JobInfo &info);
372 };
373 
374 #endif
375 
const UT_Vector3 & getBBoxOrig() const
int x() const
Retrieve the current location of the iterator.
GLbyte * weights
Definition: glew.h:7551
const UT_ValArray< sim_extrapelem > * elements
const UT_VoxelArrayI * field() const
GLsizeiptr size
Definition: glew.h:1681
GLenum src
Definition: glew.h:2410
exint getBorderValue() const
const openvdb::tools::PointIndexGrid * ptgridvdb
UT_Array< int64 > Indices
exint operator()(int x, int y, int z) const
exint maxIndex() const
FMT_CONSTEXPR auto begin(const C &c) -> decltype(c.begin())
Definition: format.h:251
#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
const UT_Vector3 & getVoxelSize() const
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
GLdouble GLdouble z
Definition: glew.h:1559
UT_VoxelArrayI * myField
SIM_FieldSample mySample
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
GLenum clamp
Definition: glew.h:2166
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: glew.h:1254
GLuint GLuint end
Definition: glew.h:1253
const UT_Vector3 & getSize() const
void
Definition: png.h:1083
#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)
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...
const UT_Vector3 & getOrig() const
#define SIM_API
Definition: SIM_API.h:10
const SIM_RawField::sim_particleToFieldParms * ptfparms
UT_VoxelArrayI * fieldNC() const
#define const
Definition: zconf.h:214
UT_Array< Box > Boxes
SYS_FORCE_INLINE Storage::MathFloat length() const
fpreal getVoxelDiameter() const
void setBorder(UT_VoxelBorderType border, exint bval)
exint getIndex(const UT_VoxelArrayIteratorF &vit) const
UT_ValArray< UT_ValArray< sim_extrapelem > > * newelemlists