00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __SIM_VectorField__
00020 #define __SIM_VectorField__
00021
00022 #include "SIM_API.h"
00023
00024 #include <UT/UT_VoxelArray.h>
00025 #include <UT/UT_DMatrix3.h>
00026 #include <UT/UT_ThreadedAlgorithm.h>
00027
00028 #include "SIM_Names.h"
00029 #include "SIM_OptionsUser.h"
00030 #include "SIM_DataUtils.h"
00031 #include "SIM_RawField.h"
00032
00033 class UT_IStream;
00034 class SIM_Geometry;
00035 class SIM_RawField;
00036 class SIM_ScalarField;
00037 class SIM_MatrixField;
00038 class SIM_IndexField;
00039
00040
00041 class SIM_API SIM_VectorField : public SIM_Data,
00042 public SIM_OptionsUser
00043 {
00044 public:
00045
00046 GETSET_DATA_FUNCS_I(SIM_NAME_UNIFORMVOXELS, UniformVoxels);
00047 GETSET_DATA_FUNCS_B(SIM_NAME_TWOD, TwoDField);
00048 GETSET_DATA_FUNCS_I(SIM_NAME_VOXELPLANE, VoxelPlane);
00049 GETSET_DATA_FUNCS_V3(SIM_NAME_DIV, RawDivisions);
00050 GETSET_DATA_FUNCS_I("uniformdiv", RawUniformDivisions);
00051 GETSET_DATA_FUNCS_V3(SIM_NAME_CENTER, RawCenter);
00052 GETSET_DATA_FUNCS_V3(SIM_NAME_SIZE, RawSize);
00053
00054 GETSET_DATA_FUNCS_V3("slicediv", SliceDivisions);
00055 GETSET_DATA_FUNCS_V3("sliceoverlapneg", SliceOverlapNeg);
00056 GETSET_DATA_FUNCS_V3("sliceoverlappos", SliceOverlapPos);
00057 GETSET_DATA_FUNCS_I("slice", Slice)
00058
00059 GETSET_DATA_FUNCS_I(SIM_NAME_VOXELSAMPLE, VoxelSampleRaw);
00060 GETSET_DATA_FUNCS_B("closedends", ClosedEnds);
00061 GETSET_DATA_FUNCS_B("closexneg", CloseXNeg);
00062 GETSET_DATA_FUNCS_B("closeyneg", CloseYNeg);
00063 GETSET_DATA_FUNCS_B("closezneg", CloseZNeg);
00064 GETSET_DATA_FUNCS_B("closexpos", CloseXPos);
00065 GETSET_DATA_FUNCS_B("closeypos", CloseYPos);
00066 GETSET_DATA_FUNCS_B("closezpos", CloseZPos);
00067
00068 GETSET_DATA_FUNCS_V3(SIM_NAME_DIRECTION, ExternalDirection);
00069 GETSET_DATA_FUNCS_F(SIM_NAME_TOLERANCE, Tolerance);
00070 GETSET_DATA_FUNCS_I("border", RawBorder);
00071 UT_VoxelBorderType getBorder() const { return (UT_VoxelBorderType) getRawBorder(); }
00072
00073
00074
00075 void getBBox(UT_BoundingBox &bbox) const;
00076
00077 UT_Vector3 getOrig() const
00078 {
00079 return getCenter() - getSize()/2;
00080 }
00081
00082
00083
00084 UT_Vector3 getDivisions() const;
00085 UT_Vector3 getSize() const;
00086 UT_Vector3 getCenter() const;
00087
00088
00089
00090 void setDivisions(const UT_Vector3 &div);
00091 void setSize(const UT_Vector3 &div);
00092 void setCenter(const UT_Vector3 &div);
00093
00094
00095
00096
00097
00098
00099 void resizeKeepData(const UT_Vector3 &size, const UT_Vector3 ¢er);
00100
00101
00102
00103
00104 void matchField(const SIM_ScalarField *field);
00105 void matchField(const SIM_VectorField *field, bool matchsample = false);
00106 void matchField(const SIM_MatrixField *field);
00107 void matchField(const SIM_IndexField *field);
00108
00109 bool isAligned(const SIM_ScalarField *field) const;
00110 bool isAligned(const SIM_MatrixField *field) const;
00111
00112
00113 bool isAligned(const SIM_VectorField *field) const;
00114 bool isAligned(const SIM_RawField *field) const;
00115
00116
00117
00118
00119
00120
00121 bool isMatching(const SIM_VectorField *field) const
00122 { return getField(0)->isMatching(field->getField(0)); }
00123
00124 bool isFaceSampled() const
00125 { return getVoxelSample(0) == SIM_SAMPLE_FACEX &&
00126 getVoxelSample(1) == SIM_SAMPLE_FACEY &&
00127 getVoxelSample(2) == SIM_SAMPLE_FACEZ; }
00128
00129 bool isCenterSampled() const
00130 { return getVoxelSample(0) == SIM_SAMPLE_CENTER &&
00131 getVoxelSample(1) == SIM_SAMPLE_CENTER &&
00132 getVoxelSample(2) == SIM_SAMPLE_CENTER; }
00133
00134
00135 bool isSelfAligned() const
00136 { return getVoxelSample(0) == getVoxelSample(1) &&
00137 getVoxelSample(1) == getVoxelSample(2); }
00138
00139
00140 SIM_FieldSample getVoxelSample(int axis) const;
00141 const UT_Vector3 &getVoxelSize(int axis) const;
00142 fpreal getVoxelDiameter(int axis) const;
00143
00144
00145
00146 UT_Vector3 getValue(const UT_Vector3 &pos) const;
00147
00148
00149 UT_DMatrix3 getGradient(const UT_Vector3 &pos) const;
00150
00151
00152 UT_Vector3 getCurl(const UT_Vector3 &pos) const;
00153
00154
00155
00156 UT_Vector3 getCellValue(int x, int y, int z) const;
00157
00158
00159
00160
00161 void addToCell(int x, int y, int z, const UT_Vector3 &dv);
00162
00163
00164
00165
00166 void advect(UT_Vector3 &pos, fpreal time) const;
00167
00168
00169 void advectMidpoint(UT_Vector3 &pos, fpreal time) const;
00170
00171
00172
00173 void advect(const SIM_VectorField *vel, fpreal timestep,
00174 const SIM_RawField *collision = 0,
00175 SIM_FieldAdvection advectmethod = SIM_ADVECT_TRACE);
00176 void advect(sim_PointVelocity getVelocity, fpreal timestep,
00177 fpreal voxelsize,
00178 const SIM_RawField *collision = 0);
00179
00180
00181
00182 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);
00183 void projectToNonDivergentCenter(const SIM_RawField *pressureboundary, const SIM_RawField *goaldiv, int numiter);
00184 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);
00185
00186
00187 THREADED_METHOD1_CONST(SIM_VectorField, getField(0)->shouldMultiThread(),
00188 buildDivergenceCenter,
00189 SIM_RawField &, div)
00190 void buildDivergenceCenterPartial(SIM_RawField &div,
00191 const UT_JobInfo &info) const;
00192
00193
00194
00195 THREADED_METHOD4(SIM_VectorField, getField(axis)->shouldMultiThread(),
00196 applyPressureGradientFace,
00197 int, axis,
00198 const SIM_RawField *, pressure,
00199 const SIM_RawField *, surface,
00200 const SIM_RawIndexField *, comp)
00201 void applyPressureGradientFacePartial(int axis,
00202 const SIM_RawField *pressure,
00203 const SIM_RawField *surface,
00204 const SIM_RawIndexField *comp,
00205 const UT_JobInfo &info);
00206
00207
00208 THREADED_METHOD1(SIM_VectorField, getField(0)->shouldMultiThread(),
00209 applyPressureGradientCenter,
00210 const SIM_RawField *, pressure)
00211 void applyPressureGradientCenterPartial(
00212 const SIM_RawField *pressure,
00213 const UT_JobInfo &info);
00214
00215
00216
00217 void distributeBoundaryDivergenceToVolumeFace(SIM_RawField &div, const SIM_RawField *pressureboundary = 0, int compnum = -1, const SIM_RawIndexField *comp = 0);
00218
00219
00220 bool hasSurfaceCell(SIM_RawField &div, const SIM_RawField *pressureboundary, const SIM_RawField *collision, int compnum, const SIM_RawIndexField &comp) const;
00221
00222
00223
00224
00225 void distributeBoundaryDivergenceToSurfaceFace(SIM_RawField &div, const SIM_RawField *pressureboundary, const SIM_RawField *collision, int compnum, const UT_VoxelArray<int64> &comp);
00226
00227
00228 void enforceBoundary(const SIM_ScalarField *collision=0,
00229 const SIM_VectorField *cvel = 0);
00230
00231
00232
00233
00234
00235
00236
00237 void enforceVelBoundary(const SIM_ScalarField *collision,
00238 UT_Vector3 calcVelocity(const UT_Vector3 &pos,
00239 void *vp),
00240 void *vvp,
00241 void calcPhysParms(const UT_Vector3 &pos, void *vp,
00242 fpreal &bounce,
00243 fpreal &friction,
00244 fpreal &dynfriction),
00245 void *vpp,
00246 bool forbidinterference);
00247
00248
00249 bool indexToPos(int axis, int x, int y, int z, UT_Vector3 &pos) const;
00250
00251
00252 bool posToIndex(int axis, const UT_Vector3 &pos, int &x, int &y, int &z) const;
00253
00254
00255 SIM_RawField *getField(int axis) const { return myFields[axis]; }
00256 SIM_RawField *getXField() const { return myFields[0]; }
00257 SIM_RawField *getYField() const { return myFields[1]; }
00258 SIM_RawField *getZField() const { return myFields[2]; }
00259
00260
00261
00262 void setField(int axis, SIM_RawField *field);
00263
00264
00265
00266 SIM_RawField *stealField(int axis);
00267
00268 void pubHandleModification()
00269 {
00270 handleModification();
00271 }
00272
00273
00274 GU_ConstDetailHandle createSmokeRepresentation(const SIM_RootData &root) const;
00275
00276
00277
00278 void addSmokeRepresentation(const SIM_RootData &root, GU_Detail *gdp) const;
00279
00280 protected:
00281 explicit SIM_VectorField(const SIM_DataFactory *factory);
00282 virtual ~SIM_VectorField();
00283
00284
00285 virtual void initializeSubclass();
00286
00287 virtual void makeEqualSubclass(const SIM_Data *source);
00288
00289
00290 virtual void saveSubclass(ostream &os) const;
00291
00292 virtual bool loadSubclass(UT_IStream &is);
00293
00294 virtual int64 getMemorySizeSubclass() const;
00295
00296
00297 virtual void optionChangedSubclass(const char *name);
00298
00299 private:
00300 static const SIM_DopDescription *getVectorFieldDopDescription();
00301
00302 SIM_RawField *myFields[3];
00303
00304 void rebuildFields();
00305
00306 DECLARE_STANDARD_GETCASTTOTYPE();
00307
00308 DECLARE_DATAFACTORY(SIM_VectorField,
00309 SIM_Data,
00310 "VectorField",
00311 getVectorFieldDopDescription());
00312 };
00313 #endif
00314