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