HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_ScalarField.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_ScalarField.h ( SIM Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __SIM_ScalarField__
12 #define __SIM_ScalarField__
13 
14 #include "SIM_API.h"
15 
16 #include <UT/UT_VoxelArray.h>
17 
18 #include "SIM_Names.h"
19 #include "SIM_OptionsUser.h"
20 #include "SIM_DataUtils.h"
21 #include "SIM_RawField.h"
22 
23 class UT_IStream;
24 class SIM_Geometry;
25 class SIM_VectorField;
26 class SIM_MatrixField;
27 class SIM_IndexField;
28 
29 /// This class holds a three dimensional scalar field.
31  public SIM_OptionsUser
32 {
33 public:
35 
36  /// Accesses the relative path to the position data associated with
37  /// this geometry.
39 
40  /// Control the number of divisions.
44  GETSET_DATA_FUNCS_V3(SIM_NAME_DIV, RawDivisions);
45  GETSET_DATA_FUNCS_I("uniformdiv", RawUniformDivisions);
46  GETSET_DATA_FUNCS_F("divsize", RawDivisionSize);
49 
50  GETSET_DATA_FUNCS_V3("slicediv", SliceDivisions);
51  GETSET_DATA_FUNCS_V3("sliceoverlapneg", SliceOverlapNeg);
52  GETSET_DATA_FUNCS_V3("sliceoverlappos", SliceOverlapPos);
53  GETSET_DATA_FUNCS_I("slice", Slice)
54 
55  exint getNumSlices() const { UT_Vector3D nslice = getSliceDivisions(); return exint(nslice.x() * nslice.y() * nslice.z()); }
56 
57  GETSET_DATA_FUNCS_I("totalvoxels", TotalVoxels);
58  GETSET_DATA_FUNCS_V3("totalvoxelres", TotalVoxelRes);
59 
61  GETSET_DATA_FUNCS_F("initialvalue", InitialValue);
63  GETSET_DATA_FUNCS_B("usefp16", UseFP16);
64  GETSET_DATA_FUNCS_I("border", RawBorder);
66  {
67  if (getRawBorder() == 3)
68  return UT_VOXELBORDER_MIRROR;
69  return (UT_VoxelBorderType) getRawBorder();
70  }
72  {
73  if (border == UT_VOXELBORDER_MIRROR)
74  setRawBorder(3);
75  setRawBorder(border);
76  }
77 
78  /// Controls the dimensions of where the field is properly defined
79  /// in the field space.
80  void getBBox(UT_BoundingBox &bbox) const;
81 
83  {
84  return getCenter() - getSize()/2;
85  }
86 
87  /// Calculate the size and divisions according to options
88  /// such as 2d or equal sized voxels.
89  UT_Vector3 getDivisions() const;
90  UT_Vector3 getSize() const;
91  UT_Vector3 getCenter() const;
92 
93  /// Adjusts the size/divisions of this field, overriding
94  /// and twod or uniform voxel settings.
95  void setDivisions(const UT_Vector3 &div);
96  void setSize(const UT_Vector3 &size);
97  void setCenter(const UT_Vector3 &center);
98 
99  /// Resizes our field keeping our field data.
100  /// The final size will be an integer number of voxels matching
101  /// our current voxel size. The final center will be an integer
102  /// number of voxel offset from our current center. This allows
103  /// us to do a perfect copy of the data.
104  void resizeKeepData(const UT_Vector3 &size, const UT_Vector3 &center, bool keepdata, const char *address = 0, int port = -1);
105 
106  /// Match this field to the given reference field. We will
107  /// end up with the same size/divisions/twod/uniform,
108  /// but not the same sampling pattern
109  /// This will destroy our field data.
110  void matchField(const SIM_ScalarField *field, bool matchsample = false);
111  void matchField(const SIM_VectorField *field);
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  SIM_FieldSample getVoxelSample() const;
119  void setVoxelSample(SIM_FieldSample sample);
120 
121  const UT_Vector3 &getVoxelSize() const { return myField->getVoxelSize(); }
122  void setVoxelSize(const UT_Vector3 &voxelsize)
123  { myField->setVoxelSize(voxelsize); }
124  fpreal getVoxelDiameter() const { return myField->getVoxelDiameter(); }
125 
126  /// Access the field value given a world space location.
127  /// This does trilinear interpolation.
128  fpreal getValue(const UT_Vector3 &pos) const;
129 
130  /// Determines the gradient at the given location.
131  UT_Vector3 getGradient(const UT_Vector3 &pos) const;
132 
133  /// Advects this field by the other given field.
134  void advect(const SIM_VectorField *vel, float timestep,
135  const SIM_RawField *collision,
136  SIM_FieldAdvection advectmethod,
137  float cfl);
138  void advect(sim_PointVelocity getVelocity, float timestep,
139  float voxelsize,
140  const SIM_RawField *collision = 0,
141  float cfl = 1.0f);
142  /// Advects this by the velocity field, storing our min/max
143  /// interpolants into the min/max fields
144  void advectMinMax(SIM_ScalarField *minfield,
145  SIM_ScalarField *maxfield,
146  const SIM_VectorField *vel, float timestep,
147  const SIM_RawField *collision,
148  SIM_FieldAdvection advectmethod,
149  float cfl);
150 
151  /// Enforces the boundary condition with the given collision mask
152  void enforceBoundary(const SIM_ScalarField *collision=0,
153  const SIM_ScalarField *colvalue=0,
154  const SIM_ScalarField *boundvalue=0);
155 
156  /// Converts an integer index into a worldspace position.
157  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
158 
159  /// Converts a worldspace position into an integer index.
160  bool posToIndex(const UT_Vector3 &pos, int &x, int &y, int &z) const;
161 
162  /// Retrieve raw field.
163  const SIM_RawField *getField() const { return myField; };
164  SIM_RawField *getField() { return myField; };
165 
166  /// Sets the field to the given field, gaining ownership of it.
167  void setField(SIM_RawField *field);
168 
169  /// True if we contain any NANs
170  bool hasNan() const { return getField()->hasNan(); }
171 
172  /// True if we have a constant value. Ignores end conditions
173  /// in determining this. Used as a rough guess that the field
174  /// is unused.
175  bool appearsToBeUnused() const
176  { return getField()->field()->isConstant(0); }
177 
178  /// Steals the field, replacing this copy with an empty field and
179  /// returning the old version.
180  SIM_RawField *stealField();
181 
182  void testForNan() const;
183 
184  /// Signals to the field that it has been altered externally.
186  {
187  testForNan();
189  }
191  { getField()->markGridAsChanged(); }
192 
193  /// Recomputes total number of voxels to be stored
194  /// on our options data for ease of reading
195  void updateTotalVoxels();
196 
197  /// Creates a GDP with us as a Volume Primitive inside it.
198  GU_ConstDetailHandle createSmokeRepresentation(const SIM_Data &root) const;
199 
200  /// Adds a volume primitive version of our field to the given
201  /// gdp.
202  void addSmokeRepresentation(const SIM_Data &root, GU_Detail *gdp) const;
203 
204 protected:
205  explicit SIM_ScalarField(const SIM_DataFactory *factory);
206  ~SIM_ScalarField() override;
207 
208  /// Overrides to properly implement this class as a SIM_Data.
209  void initializeSubclass() override;
210  /// myField aware copy constructor.
211  void makeEqualSubclass(const SIM_Data *source) override;
212 
213  /// Saves our attributes, and our internal data if it has been set.
214  void saveSubclass(std::ostream &os) const override;
215  /// Loads our attributes and internal data if it was set when we saved.
216  bool loadSubclass(UT_IStream &is) override;
217 
218  int64 getMemorySizeSubclass() const override;
219 
220  /// Override the setDivisions to rebuild our voxel array on demand.
221  void optionChangedSubclass(const char *name) override;
222 
223 private:
224  /// This method can be used to signal to this field not to attempt rebuilding
225  /// the raw field on option changes.
226  void setSkipFieldRebuildOnOptionChanged(bool skip)
227  {
228  mySkipFieldRebuild = skip;
229  }
230  /// Returns whether or not this field is set to skip rebuilding its raw field
231  /// on option changes.
232  bool getSkipFieldRebuildOnOptionChanged() const
233  {
234  return mySkipFieldRebuild;
235  }
236  /// This flag can be used to signal that the raw fields are not to be rebuilt due
237  /// to option changes.
238  bool mySkipFieldRebuild;
239 
240  friend class SkipFieldRebuildScope;
241 
242 public:
243  /// This helper class can be used to prevent the given field from automatically
244  /// attempting to rebuild its raw fields on option changes. The field will skip
245  /// rebuilds as long as this object remains in scope; the rebuild flag is reset
246  /// and rebuildField() is called when the object goes out of scope.
248  {
249  public:
251  {
252  myField = field;
253  myStashedValue = myField->getSkipFieldRebuildOnOptionChanged();
254  myField->setSkipFieldRebuildOnOptionChanged(true);
255  }
256 
258  {
259  myField->setSkipFieldRebuildOnOptionChanged(myStashedValue);
260  // Only invoke possible rebuilding if the old value was set to not
261  // skip.
262  if (!myStashedValue)
263  myField->rebuildField();
264  }
265 
266  private:
267  SIM_ScalarField* myField;
268  bool myStashedValue;
269  };
270 
271 private:
272  static const SIM_DopDescription *getScalarFieldDopDescription();
273 
274  /// Rebuilds our raw field so it matches our current parameters.
275  void rebuildField();
276 
277  SIM_RawField *myField;
278 
279  /// When creating a new scalar field, we do the following:
280  /// 1) Load default values, triggering rebuildField()
281  /// 2) Call initialize()
282  /// 3) Load actual parameters values, triggering rebuildField()
283  /// We need to set the initial value in the third stage. The
284  /// problem is that if there is a non-zero default and the other
285  /// parameters are all default, stage 3 will be skipped. We thus
286  /// track our last default to avoid this case.
287  fpreal myStashedInitialValue;
288 
290 
292  SIM_Data,
293  "ScalarField",
294  getScalarFieldDopDescription());
295 };
296 #endif
297 
#define SIM_NAME_VOXELPLANE
Definition: SIM_Names.h:218
#define SIM_NAME_POSITIONPATH
Definition: SIM_Names.h:169
virtual void makeEqualSubclass(const SIM_Data *source)
bool hasNan() const
True if we contain any NANs.
#define SIM_NAME_VOXELSAMPLE
Definition: SIM_Names.h:217
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:50
GA_API const UT_StringHolder div
virtual bool loadSubclass(UT_IStream &is)
#define SIM_NAME_TOLERANCE
Definition: SIM_Names.h:202
void pubHandleModification()
Signals to the field that it has been altered externally.
virtual void optionChangedSubclass(const char *name)
#define GETSET_DATA_FUNCS_B(DataName, FuncName)
#define SIM_NAME_CENTER
Definition: SIM_Names.h:82
void skip(T &in, int n)
Definition: ImfXdr.h:613
#define GETSET_DATA_FUNCS_S(DataName, FuncName)
#define SIM_NAME_DIV
Definition: SIM_Names.h:109
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
virtual int64 getMemorySizeSubclass() const
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
int64 exint
Definition: SYS_Types.h:125
UT_VoxelBorderType
Definition: UT_VoxelArray.h:70
const UT_Vector3 & getVoxelSize() const
GLint y
Definition: glcorearb.h:103
SIM_RawField * getField()
This class holds a three dimensional scalar field.
bool appearsToBeUnused() const
#define GETSET_DATA_FUNCS_F(DataName, FuncName)
#define GETSET_DATA_FUNCS_V3(DataName, FuncName)
__hostdev__ float getValue(uint32_t i) const
Definition: NanoVDB.h:5578
SIM_FieldSample
Definition: SIM_RawField.h:38
#define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms)
Definition: SIM_DataUtils.h:63
#define SIM_NAME_SIZE
Definition: SIM_Names.h:184
UT_Vector3 getOrig() const
GLfloat f
Definition: glcorearb.h:1926
SIM_RawField rawfield_type
SkipFieldRebuildScope(SIM_ScalarField *field)
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
virtual void saveSubclass(std::ostream &os) const
#define SIM_NAME_UNIFORMVOXELS
Definition: SIM_Names.h:208
#define GETSET_DATA_FUNCS_I(DataName, FuncName)
long long int64
Definition: SYS_Types.h:116
#define SIM_NAME_TWOD
Definition: SIM_Names.h:207
GLuint const GLchar * name
Definition: glcorearb.h:786
fpreal getVoxelDiameter() const
This class holds a three dimensional tensor field.
GLint GLenum GLint x
Definition: glcorearb.h:409
const SIM_RawField * getField() const
Retrieve raw field.
GLsizeiptr size
Definition: glcorearb.h:664
GLint GLint GLsizei GLint border
Definition: glcorearb.h:108
fpreal64 fpreal
Definition: SYS_Types.h:277
UT_VoxelBorderType getBorder() const
void handleModification(int code=-1)
SIM_FieldAdvection
Definition: SIM_RawField.h:60
#define SIM_API
Definition: SIM_API.h:12
This class holds a three dimensional scalar field.
void setVoxelSize(const UT_Vector3 &voxelsize)
void setBorder(UT_VoxelBorderType border)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
This class holds a three dimensional vector field.
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663
virtual void initializeSubclass()