HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 
65  /// Initialize this to be the same dimension and sampling
66  /// patern as the given field.
67  void match(const SIM_RawField &src);
68  void match(const SIM_RawIndexField &src);
69 
70  /// Sets this field to a constant value
71  void makeConstant(exint cval);
72 
73  /// Convert indices to world coordinates and vice-versa. Note this uses
74  /// this field's indices which change depending on sampling.
75  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
76  bool indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
77 
78  /// Converts a worldspace position into an integer index.
79  bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
80 
81  /// Returns true if the given field and this one match in terms
82  /// of number of voxels and bounding box size.
83  /// This means the voxel cells match - not necessarily the sample
84  /// points!
85  bool isMatching(const SIM_RawIndexField *field) const;
86 
87  /// Returns true if the two fields are precisely aligned. This
88  /// means that samples are matched so a given integer index
89  /// into either field would give the same result.
90  bool isAligned(const SIM_RawIndexField *field) const;
91  bool isAligned(const SIM_RawField *field) const;
92 
93  exint getMemoryUsage() const;
94 
95  /// Returns the resolution of the voxel grid that we are sampling.
96  /// This is a count of voxels, so may differ for our different
97  /// sampling methods.
98  void getVoxelRes(int &xres, int &yres, int &zres) const;
99 
100  /// Returns the actual number of samples in each resolution.
101  /// Preferred over field()->getXRes() as it doesn't require a
102  /// copy of the CE fields.
103  int getXRes() const { return myField->getXRes(); }
104  int getYRes() const { return myField->getYRes(); }
105  int getZRes() const { return myField->getZRes(); }
106 
107  /// Consistently compute a world origin for what world space 0,0,0
108  /// would map to. A bit tricky as we want to avoid round off
109  /// if we line up to 0.5...
110  /// This is not necessarily 0,0,0.
111  void getWorldOrigin(int &origx, int &origy, int &origz) const;
112 
113  const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
114  fpreal getVoxelDiameter() const { return myVoxelDiameter; }
115 
116  UT_VoxelBorderType getBorder() const { return myField->getBorder(); }
117  exint getBorderValue() const { return myField->getBorderValue(); }
119  { myField->setBorder(border, bval); }
120 
121  /// Returns true if the given x, y, z values lie inside the valid index.
122  bool isValidIndex(int x, int y, int z) const
123  {
124  return field()->isValidIndex(x, y, z);
125  }
126 
127  /// Returns the set of samples in *this* field which correspond
128  /// to the given location & sampling pattern.
129  /// ix, iy, and iz should be size 8.
130  /// If you want the deltas for the sampling pattern, call with
131  /// x, y, z zero and clamp to false.
132  void getSamplePattern(SIM_FieldSample sample,
133  int x, int y, int z,
134  int &numsample,
135  int *ix, int *iy, int *iz,
136  bool clamp) const;
137 
138  /// Builds from a surface & collision field.
139  /// -1 if inside collision, -2 if not in collision and not in
140  /// surface, otherwise a unique number.
141  /// Returns maximum index (which you can also get from getMaxIndex)
142  exint buildIndex(const SIM_RawField *surface,
143  const SIM_RawField *collision);
144 
145  // Partitions the voxels into sets.
146  exint buildPartitionedIndex(const SIM_RawField *surface,
147  const SIM_RawField *collision);
148 
149  // Each voxel is an index of where we should copy our values
150  // to perform a SAME boundary collision. this should already
151  // be inited to the desired resolution.
152  // -1 for voxels that don't need collision lookups, otherwise
153  // it is x+(y+z*yres)*xres
154  // Will only write to non- -1 voxels, so call constant(-1) first.
155  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
156  buildCollisionLookup,
157  const SIM_RawField *, collision)
158  void buildCollisionLookupPartial(const SIM_RawField *collision,
160 
161  /// Computes the connected components of the given field.
162  /// Anything with a value < 0 will be considered "inside" and
163  /// connected to each other. Voxels with a value >= 0 will be
164  /// flagged as being in component -1.
165  /// The maxIndex will store the number of connected components.
166  exint computeConnectedComponents(const SIM_RawField &surface);
167 
168  /// Computes the connected components according to the given index
169  /// values. Areas of -1, -2, and >=0 will be consdiered three different
170  /// material types and connectivity computed respectively.
171  exint computeConnectedComponents(const SIM_RawIndexField &idx);
172 
173  exint computeConnectedComponentsWeighted(const SIM_RawIndexField &idx,
174  const SIM_RawField *weights[3],
175  const SIM_RawIndexField *sliceindex = 0,
176  int thisslice = -1);
177 
178  /// Computes connectivity of the -2 and >= 0 material types.
179  void computeMetaConnected(UT_IntArray &metagroups,
181 
182  /// Returns true if this should be multithreaded.
183  bool shouldMultiThread() const
184  {
185  return field()->numTiles() > 1;
186  }
187 
188  exint operator()(int x, int y, int z) const
189  {
190  return (*field())(x, y, z);
191  }
193  {
194  return (*field())(vit.x(), vit.y(), vit.z());
195  }
196 
197  exint getValue(const UT_Vector3 &pos) const;
198 
199  const UT_VoxelArrayI *field() const { return myField; }
200  UT_VoxelArrayI *fieldNC() const { return myField; }
201 
202  exint maxIndex() const { return myMaxIndex; }
203 
204  const UT_Vector3 &getOrig() const { return myOrig; }
205  const UT_Vector3 &getSize() const { return mySize; }
206  const UT_Vector3 &getBBoxOrig() const { return myBBoxOrig; }
207  const UT_Vector3 &getBBoxSize() const { return myBBoxSize; }
208 
209  SIM_FieldSample getSample() const { return mySample; }
210 
211  void extrapolateClosestPoints(const SIM_RawIndexField *altclosept,
212  const GU_Detail *gdp,
213  const openvdb::tools::PointIndexGrid *ptgridvdb,
214  fpreal uniformradius,
215  fpreal bandwidth,
216  bool rebuildsdf,
217  SIM_RawField *dest = NULL,
218  const SIM_RawField::sim_particleToFieldParms *parms = NULL);
219 
220 protected:
221 
222  /// Given a set of connectivity classes, collapse into the minimal
223  /// set and renumber from 0. myMaxIndex will be updated with the
224  /// resulting maximum & the number of components returned.
225  exint collapseClassIndices();
226 
227  /// Determines if two indices should be connected using our empty
228  /// cell merge rule.
229  bool shouldConnectIndices(exint idx1, exint idx2) const;
230 
231  THREADED_METHOD3(SIM_RawIndexField, shouldMultiThread(),
232  initConnectedComponents,
233  const SIM_RawIndexField &, idx,
234  const SIM_RawIndexField *, sliceindex,
235  int, thisslice);
236  void initConnectedComponentsPartial(const SIM_RawIndexField &idx,
237  const SIM_RawIndexField *sliceindex,
238  int thisslice,
239  const UT_JobInfo &info);
240 
241  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
242  applyLookup,
243  const UT_VoxelArrayI &, lut);
244  void applyLookupPartial(const UT_VoxelArrayI &lut,
245  const UT_JobInfo &info);
246 
250 
251  // This is the size and offset which converts our UT_VoxelArray into
252  // world coordinates.
254 
255  // This is our actual official size.
256  UT_Vector3 myBBoxOrig, myBBoxSize;
257 
258  // Cached metrics.
261 
262  // Find ranges of indices for valid voxels
263  void findRange
264  (
265  const SIM_RawField* surface,
266  const SIM_RawField* collision,
267  int begin[3],
268  int end[3]
269  ) const;
270 
271  // Count all valid voxels in a box
272  exint countVoxelsInBox
273  (
274  const SIM_RawField* surface,
275  const SIM_RawField* collision,
276  const Box& box
277  ) const;
278 
279 
280  // Closest point extrapolation functions.
282 
283  static sim_extrapelem indexToElement(const UT_VoxelArrayI &U,
284  int x, int y, int z);
285 
286  static void elementToIndex(const UT_VoxelArrayI &U, sim_extrapelem idx,
287  int &x, int &y, int &z);
288 
289  void computeQueryOffsets(const SIM_RawIndexField *nindex,
290  int nsamples,
291  const int *dx, const int *dy, const int *dz,
292  UT_Vector3Array &queryoffsets,
293  UT_ValArray<fpreal> &radii) const;
294 
296  {
300  const GU_Detail *gdp;
307  };
308 
309  THREADED_METHOD1(SIM_RawIndexField, shouldMultiThread(),
310  buildActiveLists,
311  const sim_buildActiveParms &, parms);
312 
313  void buildActiveListsPartial(const sim_buildActiveParms &parms,
314  const UT_JobInfo &info);
315 
316  THREADED_METHOD4(SIM_RawIndexField, tileoccupied.entries() > 10,
317  uncompressActiveTiles,
318  UT_VoxelArrayI &, closept,
319  UT_VoxelArrayI &, newclosept,
320  UT_VoxelArrayF *, dest,
321  const UT_ValArray<bool> &, tileoccupied);
322 
323  void uncompressActiveTilesPartial(UT_VoxelArrayI &closept,
324  UT_VoxelArrayI &newclosept,
325  UT_VoxelArrayF *dest,
326  const UT_ValArray<bool> &tileoccupied,
327  const UT_JobInfo &info);
328 
330  {
331  const GU_Detail *gdp;
342  };
343 
344  THREADED_METHOD1(SIM_RawIndexField, parms.elements->entries() > 50,
345  extrapolateActiveElements,
346  const sim_extrapActiveParms &, parms);
347 
348  void extrapolateActiveElementsPartial(const sim_extrapActiveParms &parms,
349  const UT_JobInfo &info);
350 
351  THREADED_METHOD4(SIM_RawIndexField, elements.entries() > 100,
352  applyExtrapolatedParticleToField,
353  const UT_ValArray<sim_extrapelem> &, elements,
354  const GU_Detail *, gdp,
355  SIM_RawField *, dest,
356  const SIM_RawField::sim_particleToFieldParms &, ptfparms);
357 
358  void applyExtrapolatedParticleToFieldPartial(
360  const GU_Detail *gdp,
361  SIM_RawField *dest,
363  const UT_JobInfo &info);
364 };
365 
366 #endif
367 
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:69
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:109
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)
double fpreal
Definition: SYS_Types.h:263
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
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