HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SIM_VectorField.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_VectorField.h ( SIM Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __SIM_VectorField__
12 #define __SIM_VectorField__
13 
14 #include "SIM_API.h"
15 
16 #include <UT/UT_VoxelArray.h>
17 #include <UT/UT_DMatrix3.h>
19 
20 #include "SIM_Names.h"
21 #include "SIM_OptionsUser.h"
22 #include "SIM_DataUtils.h"
23 #include "SIM_RawField.h"
24 
25 class UT_IStream;
26 class SIM_Geometry;
27 class SIM_RawField;
28 class SIM_ScalarField;
29 class SIM_MatrixField;
30 class SIM_IndexField;
31 class GEO_PrimVDB;
32 
33 /// This class holds a three dimensional vector field.
35  public SIM_OptionsUser
36 {
37 public:
39 
40  /// Accesses the relative path to the position data associated with
41  /// this geometry.
43 
44  /// Control the number of divisions.
48  GETSET_DATA_FUNCS_V3(SIM_NAME_DIV, RawDivisions);
49  GETSET_DATA_FUNCS_I("uniformdiv", RawUniformDivisions);
50  GETSET_DATA_FUNCS_F("divsize", RawDivisionSize);
53 
54  GETSET_DATA_FUNCS_V3("slicediv", SliceDivisions);
55  GETSET_DATA_FUNCS_V3("sliceoverlapneg", SliceOverlapNeg);
56  GETSET_DATA_FUNCS_V3("sliceoverlappos", SliceOverlapPos);
57  GETSET_DATA_FUNCS_I("slice", Slice)
58  exint getNumSlices() const { UT_Vector3D nslice = getSliceDivisions(); return exint(nslice.x() * nslice.y() * nslice.z()); }
59 
60  GETSET_DATA_FUNCS_I("totalvoxels", TotalVoxels);
61  GETSET_DATA_FUNCS_V3("totalvoxelres", TotalVoxelRes);
62 
64  GETSET_DATA_FUNCS_B("closedends", ClosedEnds);
65  GETSET_DATA_FUNCS_B("closexneg", CloseXNeg);
66  GETSET_DATA_FUNCS_B("closeyneg", CloseYNeg);
67  GETSET_DATA_FUNCS_B("closezneg", CloseZNeg);
68  GETSET_DATA_FUNCS_B("closexpos", CloseXPos);
69  GETSET_DATA_FUNCS_B("closeypos", CloseYPos);
70  GETSET_DATA_FUNCS_B("closezpos", CloseZPos);
71 
72  GETSET_DATA_FUNCS_V3(SIM_NAME_DIRECTION, ExternalDirection);
74  GETSET_DATA_FUNCS_B("usefp16", UseFP16);
75  GETSET_DATA_FUNCS_I("border", RawBorder);
76  UT_VoxelBorderType getBorder() const { return (UT_VoxelBorderType) getRawBorder(); }
77  void setBorder(UT_VoxelBorderType border) { setRawBorder(border); }
78 
79  /// Controls the dimensions of where the field is properly defined
80  /// in the field space.
81  void getBBox(UT_BoundingBox &bbox) const;
82 
84  {
85  return getCenter() - getSize()/2;
86  }
87 
88  /// Calculate the size and divisions according to options
89  /// such as 2d or equal sized voxels.
90  UT_Vector3 getDivisions() const;
91  UT_Vector3 getSize() const;
92  UT_Vector3 getCenter() const;
93 
94  /// Adjusts the size/divisions of this field, overriding
95  /// and twod or uniform voxel settings.
96  void setDivisions(const UT_Vector3 &div);
97  void setSize(const UT_Vector3 &div);
98  void setCenter(const UT_Vector3 &div);
99 
100  /// Resizes our field keeping our field data.
101  /// The final size will be an integer number of voxels matching
102  /// our current voxel size. The final center will be an integer
103  /// number of voxel offset from our current center. This allows
104  /// us to do a perfect copy of the data.
105  void resizeKeepData(const UT_Vector3 &size, const UT_Vector3 &center, bool keepdata, const char *address = 0, int port = -1);
106 
107  /// Match this field to the given reference field. We will
108  /// end up with the same size/divisions/twod/uniform,
109  /// but not the same sampling pattern
110  void matchField(const SIM_ScalarField *field);
111  void matchField(const SIM_VectorField *field, bool matchsample = false);
112  void matchField(const SIM_MatrixField *field);
113  void matchField(const SIM_IndexField *field);
114 
115  void matchVolume(const GEO_PrimVolume *vol, const UT_DMatrix4 &xform);
116  void matchVDB(const GEO_PrimVDB *vdb, const UT_DMatrix4 &xform);
117 
118  bool isAligned(const SIM_ScalarField *field) const;
119  bool isAligned(const SIM_MatrixField *field) const;
120  /// True if we are component-wise aligned, our x/y/z fields
121  /// may still be unaligned with respect to each other.
122  bool isAligned(const SIM_VectorField *field) const;
123  bool isAligned(const SIM_RawField *field) const;
124 
125  /// Determines if we match in terms of voxel cells - same bounding
126  /// box and number of cells. Due to sampling, this does not mean
127  /// the sample points will match
128  /// Because our internal fields are always matching by definition,
129  /// we can just test the first field.
130  bool isMatching(const SIM_VectorField *field) const
131  { return getField(0)->isMatching(field->getField(0)); }
132 
133  bool isFaceSampled() const
134  { return getVoxelSample(0) == SIM_SAMPLE_FACEX &&
135  getVoxelSample(1) == SIM_SAMPLE_FACEY &&
136  getVoxelSample(2) == SIM_SAMPLE_FACEZ; }
137 
138  bool isCenterSampled() const
139  { return getVoxelSample(0) == SIM_SAMPLE_CENTER &&
140  getVoxelSample(1) == SIM_SAMPLE_CENTER &&
141  getVoxelSample(2) == SIM_SAMPLE_CENTER; }
142 
143  /// True if our internal fields are aligned.
144  bool isSelfAligned() const
145  { return getVoxelSample(0) == getVoxelSample(1) &&
146  getVoxelSample(1) == getVoxelSample(2); }
147 
148 
149  SIM_FieldSample getVoxelSample(int axis) const;
150  const UT_Vector3 &getVoxelSize(int axis) const { return myFields[axis]->getVoxelSize(); }
151  fpreal getVoxelDiameter(int axis) const { return myFields[axis]->getVoxelDiameter(); }
152  // Independent of sampling pattern, so constant between fields.
153  UT_Vector3 getVoxelSize() const { return getVoxelSize(0); }
154  void setVoxelSize(const UT_Vector3 &voxelsize)
155  { myFields[0]->setVoxelSize(voxelsize);
156  myFields[1]->setVoxelSize(voxelsize);
157  myFields[2]->setVoxelSize(voxelsize);
158  }
159 
160  /// Access the field value given a world space location.
161  /// This does trilinear interpolation.
162  UT_Vector3 getValue(const UT_Vector3 &pos) const;
163 
164  /// Computes the gradient of the vector field in world space..
165  UT_DMatrix3 getGradient(const UT_Vector3 &pos) const;
166 
167  /// Computes the curl at a given worldspace
168  UT_Vector3 getCurl(const UT_Vector3 &pos) const;
169 
170  /// Gets the velocity at the given *voxel* location, interpolating
171  /// if we have corner or face velocities.
172  UT_Vector3 getCellValue(int x, int y, int z) const;
173 
174  /// Adds a velocity to the given *voxel*. If this is face,
175  /// it is divided in two and spread on each of 6 faces. If it is
176  /// corner, it is divided by 8 and spread along each of 8 corners.
177  void addToCell(int x, int y, int z, const UT_Vector3 &dv);
178 
179  /// Treats this field as a velocity field and advects the given
180  /// position for the given length of time.
181  /// Uses first order explicit euler integration
182  void advect(UT_Vector3 &pos, float time, float cfl = 1.0f) const
183  {
184  SIM_RawField::advect(pos, getXField(), getYField(), getZField(), time, 0, cfl);
185  }
186 
187  /// Uses second order explicit runge-kutta integration.
188  void advectMidpoint(UT_Vector3 &pos, float time, float cfl = 1.0f) const
189  {
190  SIM_RawField::advectMidpoint(pos, getXField(), getYField(), getZField(), time, 0, cfl);
191  }
192 
193  /// Uses third order explicit runge-kutta integration.
194  void advectRK3(UT_Vector3 &pos, float time, float cfl = 1.0f) const
195  {
196  SIM_RawField::advectRK3(pos, getXField(), getYField(), getZField(), time, 0, cfl);
197  }
198 
199  /// Uses fourth order explicit runge-kutta integration.
200  void advectRK4(UT_Vector3 &pos, float time, float cfl = 1.0f) const
201  {
202  SIM_RawField::advectRK4(pos, getXField(), getYField(), getZField(), time, 0, cfl);
203  }
204 
205  /// Advects this field by the other given field. Handles the possibility
206  /// that the other field is this field.
207  void advect(const SIM_VectorField *vel, float timestep,
208  const SIM_RawField *collision,
209  SIM_FieldAdvection advectmethod,
210  float cfl);
211  void advect(sim_PointVelocity getVelocity, float timestep,
212  float voxelsize,
213  const SIM_RawField *collision = 0,
214  float cfl = 1.0f);
215 
216  /// Advects this by the velocity field, storing our min/max
217  /// interpolants into the min/max fields
218  void advectMinMax(SIM_VectorField *minfield,
219  SIM_VectorField *maxfield,
220  const SIM_VectorField *vel, float timestep,
221  const SIM_RawField *collision,
222  SIM_FieldAdvection advectmethod,
223  float cfl);
224 
225  /// Projects the field into the space of non-divergent fields.
226  /// All divergent components of this field are removed.
227  void projectToNonDivergent(const SIM_RawField *pressureboundary = 0, const SIM_RawField *collision = 0, SIM_RawField *pressureout = 0, bool preservebubble = true, const SIM_RawField *goaldiv = 0, SIM_RawIndexField *compout = 0, bool ghostfluid = true, bool variational = true, SIM_RawField::PCG_METHOD pcgmethod = SIM_RawField::PCG_MIC, int numiterforcenter = 20);
228  void projectToNonDivergentCenter(const SIM_RawField *pressureboundary, const SIM_RawField *goaldiv, int numiter);
229  void projectToNonDivergentFace(const SIM_RawField *pressureboundary, const SIM_RawField *collision, SIM_RawField *pressureout = 0, bool preservebubble = true, const SIM_RawField *goaldiv = 0, SIM_RawIndexField *compout = 0, bool ghostfluid = true, bool variational = true, SIM_RawField::PCG_METHOD pcgmethod = SIM_RawField::PCG_MIC);
230 
231  /// Evaluates the divergence field for this velocity field.
232  THREADED_METHOD1_CONST(SIM_VectorField, getField(0)->shouldMultiThread(),
233  buildDivergenceCenter,
234  SIM_RawField &, div)
235  void buildDivergenceCenterPartial(SIM_RawField &div,
237 
238  /// Evaluates the divergence field for this velocity field.
239  THREADED_METHOD1_CONST(SIM_VectorField, getField(0)->shouldMultiThread(),
240  buildDivergenceCorner,
241  SIM_RawField &, div)
242  void buildDivergenceCornerPartial(SIM_RawField &div,
243  const UT_JobInfo &info) const;
244 
245  /// Applies a pressure differential to the given component of our
246  /// velocity field
247  THREADED_METHOD5(SIM_VectorField, getField(axis)->shouldMultiThread(),
248  applyPressureGradientFace,
249  int, axis,
250  const SIM_RawField *, pressure,
251  const SIM_RawField *, surface,
252  const SIM_RawIndexField *, comp,
253  bool, pressureBoundaryAtFace)
254  void applyPressureGradientFacePartial(int axis,
255  const SIM_RawField *pressure,
256  const SIM_RawField *surface,
257  const SIM_RawIndexField *comp,
258  bool pressureBoundaryAtFace,
259  const UT_JobInfo &info);
260 
261 
262  THREADED_METHOD1(SIM_VectorField, getField(0)->shouldMultiThread(),
263  applyPressureGradientCenter,
264  const SIM_RawField *, pressure)
265  void applyPressureGradientCenterPartial(
266  const SIM_RawField *pressure,
267  const UT_JobInfo &info);
268 
269  THREADED_METHOD1(SIM_VectorField, getField(0)->shouldMultiThread(),
270  applyPressureGradientCorner,
271  const SIM_RawField *, pressure)
272  void applyPressureGradientCornerPartial(
273  const SIM_RawField *pressure,
274  const UT_JobInfo &info);
275 
276  /// Distributes any divergence in the boundary condition among
277  /// all voxels equally.
278  void distributeBoundaryDivergenceToVolumeFace(SIM_RawField &div, const SIM_RawField *pressureboundary = 0, int compnum = -1, const SIM_RawIndexField *comp = 0);
279 
280  /// Determines if the given component has any surface cells.
281  /// result should be preloaded with false.
282  THREADED_METHOD6_CONST(SIM_VectorField, div.shouldMultiThread(),
283  hasSurfaceCell,
284  bool *, result,
285  SIM_RawField &, div,
286  const SIM_RawField *, pressureboundary,
287  const SIM_RawField *, collision,
288  int, compnum,
289  const SIM_RawIndexField &, comp)
290  void hasSurfaceCellPartial(bool *result, SIM_RawField &div, const SIM_RawField *pressureboundary, const SIM_RawField *collision, int compnum, const SIM_RawIndexField &comp, const UT_JobInfo &info) const;
291 
292  /// Distributes any divergence in the boundary condition among
293  /// all voxels that are on the boundary of the pressureboundary
294  /// but not on the collision boundary.
295  void distributeBoundaryDivergenceToSurfaceFace(SIM_RawField &div, const SIM_RawField *pressureboundary, const SIM_RawField *collision, int compnum, const UT_VoxelArray<int64> &comp);
296 
297  /// Enforces boundary conditions on the array.
298  /// Boundary line should be given in world space
299  void enforceBoundary(const SIM_ScalarField *collision=0,
300  const SIM_VectorField *cvel = 0,
301  const SIM_VectorField *bvel = 0, // Apply velocity to the SIM_BOUNDARY
302  const SIM_BoundaryLine &worldbline = SIM_BoundaryLine());
303 
304  typedef UT_Vector3 (*ut_velocityCalc)(const UT_Vector3 &pos, void *vp);
305  typedef void (*ut_physParmCalc)(const UT_Vector3 &pos, void *vp,
306  fpreal &bounce,
307  fpreal &friction,
308  fpreal &dynfriction);
309 
310 
311  /// Enforces boundary conditions on a velocity field by making
312  /// sure we are lifting from the surface, allowing tangential
313  /// motion.
314  /// forbidinterference keeps the normal enforcement behaviour of
315  /// explicitly setting all side boundaries that have a inward
316  /// pointing velocity to zero relative motion
317  /// SIM_BoundaryLine is given in world space and allows for an
318  /// open boundary to exist above a "line" in an otherwise closed
319  /// boundary.
320 
321  void enforceVelBoundary(const SIM_ScalarField *collision,
322  ut_velocityCalc calcVelocity,
323  void *vvp,
324  ut_physParmCalc calcPhysParms,
325  void *vpp,
326  bool forbidinterference,
327  const SIM_BoundaryLine &worldbline = SIM_BoundaryLine());
328 
329  /// Enforces boundary conditions on a velocity field by making
330  /// sure we are lifting from the surface, allowing tangential
331  /// motion.
332  /// forbidinterference keeps the normal enforcement behaviour of
333  /// explicitly setting all side boundaries that have a inward
334  /// pointing velocity to zero relative motion.
335  void enforceVelBoundaryVariational(const SIM_ScalarField *collision,
336  const SIM_VectorField *weights,
337  ut_velocityCalc calcVelocity,
338  void *vvp,
339  ut_physParmCalc calcPhysParms,
340  void *vpp,
341  bool threadsafe,
342  fpreal bandwidth);
343 
345  {
346  public:
347  SIM_RawField *u;
348  const SIM_VectorField *velocity;
350  ut_velocityCalc calcVelocity;
351  void *vvp;
352  ut_physParmCalc calcPhysParms;
353  void *vpp;
354  const SIM_RawField *weights;
356  int axis;
357  };
358 
359  THREADED_METHOD1(SIM_VectorField, parms.u->shouldMultiThread(),
360  enforceVelBoundaryVariationalAxis,
362 
363 
364  void enforceVelBoundaryVariationalAxisPartial(
366  const UT_JobInfo &info);
367 
368  /// Converts an integer index into a worldspace position.
369  bool indexToPos(int axis, int x, int y, int z, UT_Vector3 &pos) const;
370 
371  /// Converts a worldspace position into an integer index.
372  bool posToIndex(int axis, const UT_Vector3 &pos, int &x, int &y, int &z) const;
373 
374  /// Retrieve raw field.
375  SIM_RawField *getField(int axis) const { return myFields[axis]; }
376  SIM_RawField *getXField() const { return myFields[0]; }
377  SIM_RawField *getYField() const { return myFields[1]; }
378  SIM_RawField *getZField() const { return myFields[2]; }
379 
380  /// Sets the field to the given field, gaining ownership of it.
381  /// The new field must already match the field it will replace.
382  void setField(int axis, SIM_RawField *field);
383 
384  /// True if we contain any NANs
385  bool hasNan() const
386  { return getField(0)->hasNan() || getField(1)->hasNan() || getField(2)->hasNan(); }
387 
388  /// True if we have a constant value. Ignores end conditions
389  /// in determining this. Used as a rough guess that the field
390  /// is unused.
391  bool appearsToBeUnused() const
392  {
393  for (int i = 0; i < 3; i++)
394  if (!getField(i)->field()->isConstant(0)) return false;
395  return true;
396  }
397 
398  /// Steals the field, replacing this copy with an empty field and
399  /// returning the old version.
400  SIM_RawField *stealField(int axis);
401 
402  void testForNan() const;
403 
405  {
406  testForNan();
408  }
409 
411  { for (int i = 0; i < 3; i++) getField(i)->markGridAsChanged(); }
412 
413  /// Recomputes total number of voxels to be stored
414  /// on our options data for ease of reading
415  void updateTotalVoxels();
416 
417  /// Creates a GDP with us as a Volume Primitive inside it.
418  GU_ConstDetailHandle createSmokeRepresentation(const SIM_RootData &root) const;
419 
420  /// Adds a volume primitive version of our field to the given
421  /// gdp.
422  void addSmokeRepresentation(const SIM_RootData &root, GU_Detail *gdp) const;
423 
424 protected:
425  explicit SIM_VectorField(const SIM_DataFactory *factory);
426  virtual ~SIM_VectorField();
427 
428  /// Overrides to properly implement this class as a SIM_Data.
429  virtual void initializeSubclass();
430  /// myField aware copy constructor.
431  virtual void makeEqualSubclass(const SIM_Data *source);
432 
433  /// Saves our attributes, and our internal data if it has been set.
434  virtual void saveSubclass(std::ostream &os) const;
435  /// Loads our attributes and internal data if it was set when we saved.
436  virtual bool loadSubclass(UT_IStream &is);
437 
438  virtual int64 getMemorySizeSubclass() const;
439 
440  /// Override the setDivisions to rebuild our voxel array on demand.
441  virtual void optionChangedSubclass(const char *name);
442 
443 private:
444  static const SIM_DopDescription *getVectorFieldDopDescription();
445 
446  SIM_RawField *myFields[3];
447 
448  void rebuildFields();
449 
451 
453  SIM_Data,
454  "VectorField",
455  getVectorFieldDopDescription());
456 };
457 #endif
458 
#define SIM_NAME_VOXELPLANE
Definition: SIM_Names.h:217
#define SIM_NAME_POSITIONPATH
Definition: SIM_Names.h:168
virtual void makeEqualSubclass(const SIM_Data *source)
bool appearsToBeUnused() const
#define SIM_NAME_VOXELSAMPLE
Definition: SIM_Names.h:216
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:45
GA_API const UT_StringHolder div
SIM_RawField * getField(int axis) const
Retrieve raw field.
virtual bool loadSubclass(UT_IStream &is)
#define SIM_NAME_TOLERANCE
Definition: SIM_Names.h:201
#define THREADED_METHOD6_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5, PARMTYPE6, PARMNAME6)
virtual void optionChangedSubclass(const char *name)
static void advectRK3(UT_Vector3 &pos, const SIM_RawField *velx, const SIM_RawField *vely, const SIM_RawField *velz, float time, const SIM_RawField *collision=0, float cfl=1.0F)
Advect a point with TVD-RK3 method.
const UT_Vector3 & getVoxelSize(int axis) const
#define GETSET_DATA_FUNCS_B(DataName, FuncName)
#define SIM_NAME_DIRECTION
Definition: SIM_Names.h:101
#define SIM_NAME_CENTER
Definition: SIM_Names.h:82
#define THREADED_METHOD1(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
#define GETSET_DATA_FUNCS_S(DataName, FuncName)
#define SIM_NAME_DIV
Definition: SIM_Names.h:108
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
bool isSelfAligned() const
True if our internal fields are aligned.
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
virtual int64 getMemorySizeSubclass() const
static void advectRK4(UT_Vector3 &pos, const SIM_RawField *velx, const SIM_RawField *vely, const SIM_RawField *velz, float time, const SIM_RawField *collision=0, float cfl=1.0F)
Advect a point with TVD-RK4 method.
UT_VoxelBorderType
Definition: UT_VoxelArray.h:69
static void advectMidpoint(UT_Vector3 &pos, const SIM_RawField *velx, const SIM_RawField *vely, const SIM_RawField *velz, float time, const SIM_RawField *collision=0, float cfl=1.0F)
Advect a point with the midpoint method.
GLint y
Definition: glcorearb.h:102
This class holds a three dimensional scalar field.
SIM_RawField rawfield_type
#define GETSET_DATA_FUNCS_F(DataName, FuncName)
SYS_FORCE_INLINE T & x(void)
Definition: UT_Vector3.h:581
void setBorder(UT_VoxelBorderType border)
png_uint_32 i
Definition: png.h:2877
#define GETSET_DATA_FUNCS_V3(DataName, FuncName)
GLsizeiptr size
Definition: glcorearb.h:663
SIM_FieldSample
Definition: SIM_RawField.h:38
UT_Vector3(* sim_PointVelocity)(const UT_Vector3 &, int)
Definition: SIM_RawField.h:95
#define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms)
Definition: SIM_DataUtils.h:58
SYS_FORCE_INLINE T & z(void)
Definition: UT_Vector3.h:585
#define SIM_NAME_SIZE
Definition: SIM_Names.h:183
void pubHandleModification()
long long int64
Definition: SYS_Types.h:106
GLfloat f
Definition: glcorearb.h:1925
UT_Vector3 getVoxelSize() const
int64 exint
Definition: SYS_Types.h:115
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:802
virtual void saveSubclass(std::ostream &os) const
#define SIM_NAME_UNIFORMVOXELS
Definition: SIM_Names.h:207
#define GETSET_DATA_FUNCS_I(DataName, FuncName)
#define THREADED_METHOD5(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1, PARMTYPE2, PARMNAME2, PARMTYPE3, PARMNAME3, PARMTYPE4, PARMNAME4, PARMTYPE5, PARMNAME5)
#define SIM_NAME_TWOD
Definition: SIM_Names.h:206
bool isMatching(const SIM_VectorField *field) const
GLuint const GLchar * name
Definition: glcorearb.h:785
UT_VoxelBorderType getBorder() const
UT_Vector3 getOrig() const
This class holds a three dimensional tensor field.
SIM_RawField * getYField() const
SIM_RawField * getZField() const
bool isFaceSampled() const
#define THREADED_METHOD1_CONST(CLASSNAME, DOMULTI, METHOD, PARMTYPE1, PARMNAME1)
bool hasNan() const
True if we contain any NANs.
static void advect(UT_Vector3 &pos, const SIM_RawField *velx, const SIM_RawField *vely, const SIM_RawField *velz, float time, const SIM_RawField *collision=0, float cfl=1.0F)
Verbs that can be performed on these fields.
SYS_FORCE_INLINE T & y(void)
Definition: UT_Vector3.h:583
double fpreal
Definition: SYS_Types.h:269
GLint GLint GLsizei GLint border
Definition: glcorearb.h:107
void setVoxelSize(const UT_Vector3 &voxelsize)
void handleModification(int code=-1)
bool isCenterSampled() const
SIM_FieldAdvection
Definition: SIM_RawField.h:60
#define SIM_API
Definition: SIM_API.h:10
GLint GLenum GLint x
Definition: glcorearb.h:408
This class holds a three dimensional scalar field.
void advectRK3(UT_Vector3 &pos, float time, float cfl=1.0f) const
Uses third order explicit runge-kutta integration.
void advect(UT_Vector3 &pos, float time, float cfl=1.0f) const
#define const
Definition: zconf.h:214
SIM_RawField * getXField() const
fpreal getVoxelDiameter(int axis) const
This class holds a three dimensional vector field.
void advectRK4(UT_Vector3 &pos, float time, float cfl=1.0f) const
Uses fourth order explicit runge-kutta integration.
virtual void initializeSubclass()
void advectMidpoint(UT_Vector3 &pos, float time, float cfl=1.0f) const
Uses second order explicit runge-kutta integration.