HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_IndexField.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_IndexField.h ( SIM Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __SIM_IndexField__
12 #define __SIM_IndexField__
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 #include "SIM_RawIndexField.h"
23 
24 class UT_IStream;
25 class SIM_Geometry;
26 class SIM_ScalarField;
27 class SIM_VectorField;
28 class SIM_MatrixField;
29 
30 /// This class holds a three dimensional scalar field.
32  public SIM_OptionsUser
33 {
34 public:
36 
37  /// Accesses the relative path to the position data associated with
38  /// this geometry.
40 
41  /// Control the number of divisions.
45  GETSET_DATA_FUNCS_V3(SIM_NAME_DIV, RawDivisions);
46  GETSET_DATA_FUNCS_I("uniformdiv", RawUniformDivisions);
47  GETSET_DATA_FUNCS_F("divsize", RawDivisionSize);
50 
51  GETSET_DATA_FUNCS_V3("slicediv", SliceDivisions);
52  GETSET_DATA_FUNCS_V3("sliceoverlapneg", SliceOverlapNeg);
53  GETSET_DATA_FUNCS_V3("sliceoverlappos", SliceOverlapPos);
54  GETSET_DATA_FUNCS_I("slice", Slice)
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_I("initialvalue", InitialValue);
62  GETSET_DATA_FUNCS_I("border", RawBorder);
64  {
65  if (getRawBorder() == 3)
66  return UT_VOXELBORDER_MIRROR;
67  return (UT_VoxelBorderType) getRawBorder();
68  }
70  {
71  if (border == UT_VOXELBORDER_MIRROR)
72  setRawBorder(3);
73  setRawBorder(border);
74  }
75 
76  /// Controls the dimensions of where the field is properly defined
77  /// in the field space.
78  void getBBox(UT_BoundingBox &bbox) const;
79 
81  {
82  return getCenter() - getSize()/2;
83  }
84 
85  /// Calculate the size and divisions according to options
86  /// such as 2d or equal sized voxels.
87  UT_Vector3 getDivisions() const;
88  UT_Vector3 getSize() const;
89  UT_Vector3 getCenter() const;
90 
91  /// Adjusts the size/divisions of this field, overriding
92  /// and twod or uniform voxel settings.
93  void setDivisions(const UT_Vector3 &div);
94  void setSize(const UT_Vector3 &div);
95  void setCenter(const UT_Vector3 &div);
96 
97  /// Resizes our field keeping our field data.
98  /// The final size will be an integer number of voxels matching
99  /// our current voxel size. The final center will be an integer
100  /// number of voxel offset from our current center. This allows
101  /// us to do a perfect copy of the data.
102  void resizeKeepData(const UT_Vector3 &size, const UT_Vector3 &center, bool keepdata, const char *address = 0, int port = -1);
103 
104  /// Match this field to the given reference field. We will
105  /// end up with the same size/divisions/twod/uniform,
106  /// but not the same sampling pattern
107  void matchField(const SIM_ScalarField *field);
108  void matchField(const SIM_VectorField *field);
109  void matchField(const SIM_MatrixField *field);
110  void matchField(const SIM_IndexField *field, bool matchsamples = false);
111 
112  SIM_FieldSample getVoxelSample() const;
113 
114  const UT_Vector3 &getVoxelSize() const;
115  fpreal getVoxelDiameter() const;
116  void setVoxelSize(const UT_Vector3 &voxelsize)
117  { myField->setVoxelSize(voxelsize); }
118 
119  /// Access the field value given a world space location.
120  /// This does closest point matching.
121  exint getValue(const UT_Vector3 &pos) const;
122 
123  /// Converts an integer index into a worldspace position.
124  bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
125  bool indexToPos(exint x, exint y, exint z, UT_Vector3D &pos) const;
126 
127  /// Converts a worldspace position into an integer index.
128  bool posToIndex(const UT_Vector3 &pos, int &x, int &y, int &z) const;
129 
130  /// Retrieve raw field.
131  const SIM_RawIndexField *getField() const { return myField; };
132  SIM_RawIndexField *getField() { return myField; };
133 
134  /// Sets the field to the given field, gaining ownership of it.
135  void setField(SIM_RawIndexField *field);
136 
137  /// Can't have NANs in integer fields.
138  bool testForNan() const { return false; }
139 
140  /// True if we have a constant value. Ignores end conditions
141  /// in determining this. Used as a rough guess that the field
142  /// is unused.
143  bool appearsToBeUnused() const
144  { return getField()->field()->isConstant(0); }
145 
146  /// Steals the field, replacing this copy with an empty field and
147  /// returning the old version.
148  SIM_RawIndexField *stealField();
149 
150  /// Signals to the field that it has been altered externally.
152  {
154  }
155 
156  /// Recomputes total number of voxels to be stored
157  /// on our options data for ease of reading
158  void updateTotalVoxels();
159 
160  /// Creates a GDP with us as a Volume Primitive inside it.
161  GU_ConstDetailHandle createSmokeRepresentation(const SIM_RootData &root) const;
162 
163  /// Adds a volume primitive version of our field to the given
164  /// gdp.
165  void addSmokeRepresentation(const SIM_RootData &root, GU_Detail *gdp) const;
166 protected:
167  explicit SIM_IndexField(const SIM_DataFactory *factory);
168  ~SIM_IndexField() override;
169 
170  /// Overrides to properly implement this class as a SIM_Data.
171  void initializeSubclass() override;
172  /// myField aware copy constructor.
173  void makeEqualSubclass(const SIM_Data *source) override;
174 
175  /// Saves our attributes, and our internal data if it has been set.
176  void saveSubclass(std::ostream &os) const override;
177  /// Loads our attributes and internal data if it was set when we saved.
178  bool loadSubclass(UT_IStream &is) override;
179 
180  exint getMemorySizeSubclass() const override;
181 
182  /// Override the setDivisions to rebuild our voxel array on demand.
183  void optionChangedSubclass(const char *name) override;
184 
185 private:
186  /// This method can be used to signal to this field not to attempt rebuilding
187  /// the raw field on option changes.
188  void setSkipFieldRebuildOnOptionChanged(bool skip)
189  {
190  mySkipFieldRebuild = skip;
191  }
192  /// Returns whether or not this field is set to skip rebuilding its raw field
193  /// on option changes.
194  bool getSkipFieldRebuildOnOptionChanged() const
195  {
196  return mySkipFieldRebuild;
197  }
198  /// This flag can be used to signal that the raw fields are not to be rebuilt due
199  /// to option changes.
200  bool mySkipFieldRebuild;
201 
202  friend class SkipFieldRebuildScope;
203 
204 public:
205  /// This helper class can be used to prevent the given field from automatically
206  /// attempting to rebuild its raw fields on option changes. The field will skip
207  /// rebuilds as long as this object remains in scope; the rebuild flag is reset
208  /// and rebuildField() is called when the object goes out of scope.
210  {
211  public:
213  {
214  myField = field;
215  myStashedValue = myField->getSkipFieldRebuildOnOptionChanged();
216  myField->setSkipFieldRebuildOnOptionChanged(true);
217  }
218 
220  {
221  myField->setSkipFieldRebuildOnOptionChanged(myStashedValue);
222  // Only invoke possible rebuilding if the old value was set to not
223  // skip.
224  if (!myStashedValue)
225  myField->rebuildField();
226  }
227 
228  private:
229  SIM_IndexField* myField;
230  bool myStashedValue;
231  };
232 
233 private:
234  static const SIM_DopDescription *getIndexFieldDopDescription();
235 
236  /// Rebuilds our raw field so it matches our current parameters.
237  void rebuildField();
238 
239  SIM_RawIndexField *myField;
240 
241  /// When creating a new scalar field, we do the following:
242  /// 1) Load default values, triggering rebuildField()
243  /// 2) Call initialize()
244  /// 3) Load actual parameters values, triggering rebuildField()
245  /// We need to set the initial value in the third stage. The
246  /// problem is that if there is a non-zero default and the other
247  /// parameters are all default, stage 3 will be skipped. We thus
248  /// track our last default to avoid this case.
249  exint myStashedInitialValue;
250 
252 
254  SIM_Data,
255  "IndexField",
256  getIndexFieldDopDescription());
257 };
258 #endif
259 
#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)
#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)
virtual void optionChangedSubclass(const char *name)
SIM_RawIndexField rawfield_type
#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:711
#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
GLint y
Definition: glcorearb.h:103
This class holds a three dimensional scalar field.
#define GETSET_DATA_FUNCS_F(DataName, FuncName)
#define GETSET_DATA_FUNCS_V3(DataName, FuncName)
SIM_FieldSample
Definition: SIM_RawField.h:38
bool testForNan() const
Can't have NANs in integer fields.
#define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms)
Definition: SIM_DataUtils.h:63
#define SIM_NAME_SIZE
Definition: SIM_Names.h:184
UT_VoxelBorderType getBorder() const
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
virtual void saveSubclass(std::ostream &os) const
void setVoxelSize(const UT_Vector3 &voxelsize)
#define SIM_NAME_UNIFORMVOXELS
Definition: SIM_Names.h:208
#define GETSET_DATA_FUNCS_I(DataName, FuncName)
#define SIM_NAME_TWOD
Definition: SIM_Names.h:207
GLuint const GLchar * name
Definition: glcorearb.h:786
This class holds a three dimensional tensor field.
GLint GLenum GLint x
Definition: glcorearb.h:409
SIM_RawIndexField * getField()
GLsizeiptr size
Definition: glcorearb.h:664
GLint GLint GLsizei GLint border
Definition: glcorearb.h:108
UT_Vector3 getOrig() const
fpreal64 fpreal
Definition: SYS_Types.h:277
void handleModification(int code=-1)
const SIM_RawIndexField * getField() const
Retrieve raw field.
#define SIM_API
Definition: SIM_API.h:12
This class holds a three dimensional scalar field.
void setBorder(UT_VoxelBorderType border)
SkipFieldRebuildScope(SIM_IndexField *field)
void pubHandleModification()
Signals to the field that it has been altered externally.
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
bool appearsToBeUnused() const
This class holds a three dimensional vector field.
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663
virtual void initializeSubclass()