00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __SIM_RawField__
00020 #define __SIM_RawField__
00021
00022 #include "SIM_API.h"
00023
00024 #include <UT/UT_VoxelArray.h>
00025 #include <UT/UT_ThreadedAlgorithm.h>
00026 #include <UT/UT_Vector.h>
00027 #include <UT/UT_FloatArray.h>
00028 #include <UT/UT_SparseMatrix.h>
00029 #include <UT/UT_Wavelet.h>
00030
00031
00032
00033
00034
00035
00036 #if defined(WIN32) && !defined(AMD64)
00037 typedef UT_SparseMatrixT<fpreal32, true> SIM_RawSparseMatrix;
00038 #else
00039 typedef UT_SparseMatrixF SIM_RawSparseMatrix;
00040 #endif
00041
00042 class SIM_VectorField;
00043 class SIM_RawField;
00044 class SIM_RawIndexField;
00045 class SIM_PartitionedRawIndexField;
00046 class GEO_PrimVolume;
00047 class UT_IntArray;
00048
00049
00050
00051
00052
00053 enum SIM_FieldSample
00054 {
00055 SIM_SAMPLE_CENTER = 0,
00056 SIM_SAMPLE_FACEX = 1,
00057 SIM_SAMPLE_FACEY = 2,
00058 SIM_SAMPLE_EDGEXY = 3,
00059 SIM_SAMPLE_FACEZ = 4,
00060 SIM_SAMPLE_EDGEXZ = 5,
00061 SIM_SAMPLE_EDGEYZ = 6,
00062 SIM_SAMPLE_CORNER = 7
00063 };
00064
00065 enum SIM_FieldBoundary
00066 {
00067 SIM_BOUNDARY_NONE,
00068 SIM_BOUNDARY_SAME,
00069 SIM_BOUNDARY_ZERO,
00070 SIM_BOUNDARY_NEGATE,
00071 SIM_BOUNDARY_FIXED,
00072
00073 };
00074
00075 enum SIM_FieldAdvection
00076 {
00077 SIM_ADVECT_SINGLE = 0,
00078 SIM_ADVECT_TRACE = 1,
00079 SIM_ADVECT_MIDPOINT = 2
00080 };
00081
00082
00083 typedef UT_Vector3 (*sim_PointVelocity)(const UT_Vector3 &, int);
00084
00085 class SIM_API SIM_RawField
00086 {
00087 public:
00088 SIM_RawField();
00089 virtual ~SIM_RawField();
00090
00091
00092 SIM_RawField(const SIM_RawField &src);
00093
00094
00095 const SIM_RawField &operator=(const SIM_RawField &src);
00096
00097
00098
00099
00100
00101 void init(SIM_FieldSample sample,
00102 const UT_Vector3 &orig, const UT_Vector3 &size,
00103 int xres, int yres, int zres);
00104
00105
00106
00107
00108 void getPartialRange(UT_VoxelArrayIteratorF &vit,
00109 const UT_JobInfo &info) const;
00110
00111
00112 bool shouldMultiThread() const
00113 {
00114 #ifdef CELLBE
00115 return false;
00116 #else
00117 return field()->numTiles() > 1;
00118 #endif
00119 }
00120
00121
00122
00123
00124 void match(const SIM_RawField &src);
00125 void match(const SIM_RawIndexField &src);
00126
00127
00128
00129
00130 void resample(SIM_FieldSample sample, const SIM_RawField *src);
00131
00132
00133
00134
00135
00136
00137 void getSamplePattern(SIM_FieldSample sample, int x, int y, int z,
00138 int &numsample, int *ix, int *iy, int *iz,
00139 bool clamp) const;
00140
00141
00142
00143
00144
00145
00146
00147
00148 void extrapolate(const SIM_RawField *depths, fpreal isocontour,
00149 fpreal dir, fpreal maxdist,
00150 bool clamp, fpreal clampval);
00151
00152
00153
00154
00155
00156
00157
00158 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), moveAlongCurvature,
00159 fpreal, b_val,
00160 const SIM_RawField &, source,
00161 fpreal, timestep)
00162 void moveAlongCurvaturePartial(fpreal b_val,
00163 const SIM_RawField &source,
00164 fpreal timestep,
00165 const UT_JobInfo &jobinfo);
00166
00167
00168
00169
00170 void moveAlongCurvature(fpreal amount,
00171 fpreal cflcond,
00172 int miniter, int maxiter);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), moveAlongNormal,
00183 const SIM_RawField &, speed,
00184 const SIM_RawField &, source,
00185 fpreal, timestep)
00186 void moveAlongNormalPartial(const SIM_RawField &speed,
00187 const SIM_RawField &source,
00188 fpreal timestep, const UT_JobInfo &info);
00189
00190
00191
00192 void moveAlongNormalMidpoint(const SIM_RawField &speed,
00193 const SIM_RawField &source,
00194 fpreal timestep);
00195
00196
00197
00198
00199
00200
00201
00202 void reinitializeSignedDistance(int maxiter);
00203
00204
00205 THREADED_METHOD(SIM_RawField, shouldMultiThread(), negate)
00206 void negatePartial(const UT_JobInfo &info);
00207
00208
00209
00210
00211 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), maximum,
00212 const SIM_RawField *, other)
00213 void maximumPartial(const SIM_RawField *other, const UT_JobInfo &info);
00214
00215 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), minimum,
00216 const SIM_RawField *, other)
00217 void minimumPartial(const SIM_RawField *other, const UT_JobInfo &jobinfo);
00218
00219
00220
00221 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), average,
00222 const SIM_RawField &, other)
00223 void averagePartial(const SIM_RawField &other, const UT_JobInfo &jobinfo);
00224
00225
00226
00227 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), setScaleAdd,
00228 const SIM_RawField &, A,
00229 fpreal, scale,
00230 const SIM_RawField &, B)
00231 void setScaleAddPartial(const SIM_RawField &A,
00232 fpreal scale,
00233 const SIM_RawField &B, const UT_JobInfo &jobinfo);
00234
00235
00236
00237
00238 THREADED_METHOD2(SIM_RawField, shouldMultiThread(), smearedSign,
00239 const SIM_RawField &, sdf,
00240 fpreal, bandwidth)
00241 void smearedSignPartial(const SIM_RawField &sdf,
00242 fpreal bandwidth,
00243 const UT_JobInfo &info);
00244
00245
00246
00247 THREADED_METHOD(SIM_RawField, shouldMultiThread(), convertToHeaviside)
00248 void convertToHeavisidePartial(const UT_JobInfo &info);
00249
00250
00251 static fpreal toHeaviside(fpreal val, fpreal diam);
00252 static fpreal fromHeaviside(fpreal val, fpreal diam);
00253
00254 fpreal toHeaviside(fpreal val) const;
00255 fpreal fromHeaviside(fpreal val) const;
00256
00257
00258
00259 enum REDUCE_NAMES
00260 {
00261 REDUCE_MAX,
00262 REDUCE_MIN,
00263 REDUCE_AVERAGE,
00264 REDUCE_SUM,
00265 REDUCE_SUMABS,
00266 REDUCE_SUMSQUARE,
00267 REDUCE_RMS
00268 };
00269
00270
00271
00272
00273 fpreal reduceOp(REDUCE_NAMES op) const;
00274
00275
00276 fpreal average() const { return reduceOp(REDUCE_AVERAGE); }
00277
00278
00279
00280
00281 fpreal reduceMaskedOp(REDUCE_NAMES op,
00282 const SIM_RawField *mask, bool maskissdf) const;
00283
00284
00285
00286
00287 fpreal findProportionalValue(fpreal position,
00288 const SIM_RawField *mask, bool maskissdf) const;
00289
00290
00291
00292
00293
00294 bool isMatching(const SIM_RawField *field) const;
00295 bool isMatching(const SIM_RawIndexField *field) const;
00296
00297
00298
00299
00300 bool isAligned(const SIM_RawField *field) const;
00301 bool isAligned(const SIM_RawIndexField *field) const;
00302
00303
00304 UT_VoxelArrayF *field() const { return myField; }
00305
00306 const UT_Vector3 &getOrig() const { return myOrig; }
00307 const UT_Vector3 &getSize() const { return mySize; }
00308 const UT_Vector3 &getBBoxOrig() const { return myBBoxOrig; }
00309 const UT_Vector3 &getBBoxSize() const { return myBBoxSize; }
00310 const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
00311 fpreal getVoxelDiameter() const { return myVoxelDiameter; }
00312 fpreal getVoxelVolume() const
00313 { return myVoxelSize.x()
00314 * myVoxelSize.y()
00315 * myVoxelSize.z(); }
00316
00317 SIM_FieldSample getSample() const { return mySample; }
00318
00319 int64 getMemoryUsage() const;
00320
00321
00322
00323
00324 void getVoxelRes(int &xres, int &yres, int &zres) const;
00325
00326
00327
00328
00329 fpreal getValue(UT_Vector3 pos) const;
00330
00331
00332 fpreal getCellValue(int x, int y, int z) const;
00333
00334
00335
00336 void addToCell(int x, int y, int z, fpreal v);
00337
00338
00339
00340
00341 void setCellValue(int x, int y, int z, fpreal v);
00342
00343
00344
00345 UT_Vector3 getGradient(UT_Vector3 pos) const;
00346
00347
00348
00349 UT_Vector3 getGradientAtIndex(int x, int y, int z) const;
00350
00351
00352
00353 fpreal64 getLaplacian(UT_Vector3 pos) const;
00354
00355
00356
00357 fpreal64 getLaplacianAtIndex(int x, int y, int z) const;
00358
00359
00360
00361 fpreal64 getCurvature(UT_Vector3 pos) const;
00362
00363
00364
00365
00366
00367 fpreal64 getCurvatureAtIndex(int x, int y, int z) const;
00368
00369
00370 static fpreal64 getCurvatureAtProbe(UT_VoxelProbeCubeF &probe, const UT_Vector3 &invvoxelsize);
00371
00372
00373
00374
00375
00376 fpreal64 getCurvatureTimesGradAtIndex(int x, int y, int z) const;
00377
00378
00379
00380 fpreal64 calculateHJWENO(fpreal64 v1, fpreal64 v2, fpreal64 v3, fpreal64 v4, fpreal64 v5) const;
00381
00382
00383
00384
00385
00386 fpreal64 calculateDerivative(int x, int y, int z,
00387 int axis, bool positivegradient) const;
00388
00389
00390
00391 bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
00392
00393
00394 bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
00395
00396
00397
00398
00399 bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z,
00400 fpreal &dx, fpreal &dy, fpreal &dz) const;
00401
00402
00403
00404 bool cellIndexToPos(int x, int y, int z, UT_Vector3 &pos) const;
00405 bool posToCellIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
00406
00407
00408
00409
00410
00411 static void advect(UT_Vector3 &pos,
00412 const SIM_RawField *velx,
00413 const SIM_RawField *vely,
00414 const SIM_RawField *velz, fpreal time,
00415 const SIM_RawField *collision = 0);
00416 static void advect(UT_Vector3 &pos,
00417 sim_PointVelocity getVelocity,
00418 fpreal time, fpreal voxelsize,
00419 int jobnum = 0,
00420 const SIM_RawField *collision = 0);
00421
00422
00423 static void advectMidpoint(UT_Vector3 &pos,
00424 const SIM_RawField *velx,
00425 const SIM_RawField *vely,
00426 const SIM_RawField *velz, fpreal time,
00427 const SIM_RawField *collision = 0);
00428 static void advectMidpoint(UT_Vector3 &pos,
00429 sim_PointVelocity getVelocity,
00430 fpreal time, fpreal voxelsize,
00431 int jobnum = 0,
00432 const SIM_RawField *collision = 0);
00433
00434
00435
00436 bool movePtToIso(UT_Vector3 &pos,
00437 fpreal goaliso,
00438 fpreal maxtime,
00439 fpreal tol = 1e-4) const;
00440
00441
00442
00443
00444 THREADED_METHOD7(SIM_RawField, shouldMultiThread(), advect,
00445 const SIM_RawField *, source,
00446 const SIM_RawField *, velx,
00447 const SIM_RawField *, vely,
00448 const SIM_RawField *, velz,
00449 fpreal, time,
00450 const SIM_RawField *, collision,
00451 SIM_FieldAdvection, advectmethod
00452 )
00453 void advectPartial(const SIM_RawField *source,
00454 const SIM_RawField *velx,
00455 const SIM_RawField *vely,
00456 const SIM_RawField *velz,
00457 fpreal time,
00458 const SIM_RawField *collision,
00459 SIM_FieldAdvection advectmethod,
00460 const UT_JobInfo &info);
00461
00462 THREADED_METHOD4(SIM_RawField, shouldMultiThread(),
00463 buoyancy,
00464 const SIM_RawField *, temperature,
00465 fpreal, up,
00466 fpreal, Tamb,
00467 fpreal, buoyancy)
00468 void buoyancyPartial(const SIM_RawField *temperature,
00469 fpreal up, fpreal Tamb,
00470 fpreal buoyancy,
00471 const UT_JobInfo &info);
00472
00473 THREADED_METHOD5(SIM_RawField, shouldMultiThread(), advect2,
00474 const SIM_RawField *, source,
00475 sim_PointVelocity, getVelocity,
00476 fpreal, time, fpreal, voxelsize,
00477 const SIM_RawField *, collision)
00478 void advect2Partial(const SIM_RawField *source,
00479 sim_PointVelocity getVelocity,
00480 fpreal time, fpreal voxelsize,
00481 const SIM_RawField *collision,
00482 const UT_JobInfo &info);
00483
00484
00485
00486 void advectSelf(const SIM_RawField *velx,
00487 const SIM_RawField *vely,
00488 const SIM_RawField *velz,
00489 fpreal time,
00490 const SIM_RawField *collision,
00491 SIM_FieldAdvection advectmethod);
00492 void advectSelf(sim_PointVelocity getVelocity,
00493 fpreal time, fpreal voxelsize,
00494 const SIM_RawField *collision);
00495
00496
00497
00498
00499 void diffuse(fpreal diffrate,
00500 int numiter,
00501 const SIM_RawField *collision=0);
00502
00503
00504 static void diffuse(float *dstdata, const float *srcdata[3][3][3],
00505 float b, float ivsx, float ivsy, float ivsz,
00506 int tx, int ty,
00507 int max_xtile, int max_ytile,
00508 int max_xvox, int max_yvox);
00509
00510
00511 void computeConnectedComponents(UT_VoxelArray<int64> &comp, int &numcomponent) const;
00512
00513
00514
00515 THREADED_METHOD2(SIM_RawField, shouldMultiThread(), buildDivergenceFace,
00516 const SIM_VectorField *, vel,
00517 const SIM_RawField *, surface)
00518 void buildDivergenceFacePartial(const SIM_VectorField *vel,
00519 const SIM_RawField *surface,
00520 const UT_JobInfo &info);
00521
00522 enum PCG_METHOD
00523 {
00524 PCG_NONE,
00525 PCG_JACOBI,
00526 PCG_CHOLESKY,
00527 PCG_MIC
00528 };
00529
00530
00531
00532 void solvePressure(const SIM_RawField *divergence,
00533 const SIM_RawField *collision,
00534 int numiter = 20);
00535 void solvePressurePCG(const SIM_RawField &divergence,
00536 SIM_PartitionedRawIndexField &index,
00537 SIM_VectorField *vel,
00538 const SIM_RawIndexField *comp = 0,
00539 const UT_IntArray *expandable = 0,
00540 const SIM_RawField *surface = 0,
00541 bool variational = true,
00542 bool ghostfluid = true,
00543 PCG_METHOD pcgmethod = PCG_MIC);
00544
00545
00546
00547
00548
00549
00550 THREADED_METHOD4(SIM_RawField, shouldMultiThread(),
00551 gaussSeidelIteration,
00552 const SIM_RawField *, B,
00553 fpreal32, weight,
00554 fpreal32, sumweight,
00555 int, parity)
00556 void gaussSeidelIterationPartial(
00557 const SIM_RawField * B,
00558 fpreal32 weight,
00559 fpreal32 sumweight,
00560 int parity,
00561 const UT_JobInfo &info);
00562
00563
00564
00565
00566 THREADED_METHOD4_CONST(SIM_RawField, shouldMultiThread(),
00567 gaussSeidelIterationFlat,
00568 fpreal32 *, A,
00569 fpreal32, weight,
00570 fpreal32, sumweight,
00571 int, parity)
00572 void gaussSeidelIterationFlatPartial(
00573 fpreal32 * A,
00574 fpreal32 weight,
00575 fpreal32 sumweight,
00576 int parity,
00577 const UT_JobInfo &info) const;
00578
00579
00580
00581
00582
00583 THREADED_METHOD4_CONST(SIM_RawField, shouldMultiThread(),
00584 gaussSeidelIterationFlat2D,
00585 fpreal32 *, A,
00586 fpreal32, weight,
00587 fpreal32, sumweight,
00588 int, parity)
00589 void gaussSeidelIterationFlat2DPartial(
00590 fpreal32 * A,
00591 fpreal32 weight,
00592 fpreal32 sumweight,
00593 int parity,
00594 const UT_JobInfo &info) const;
00595
00596
00597
00598
00599
00600
00601
00602
00603 THREADED_METHOD3_CONST(SIM_RawField, shouldMultiThread(),
00604 solveLowerTriangularSystems,
00605 const UT_PtrArray<SIM_RawSparseMatrix*>&, ld,
00606 UT_RefArray<UT_VectorF>&, ys,
00607 const UT_RefArray<UT_VectorF>&, bs
00608 )
00609 void solveLowerTriangularSystemsPartial(
00610 const UT_PtrArray<SIM_RawSparseMatrix*>& ld,
00611 UT_RefArray<UT_VectorF>& ys,
00612 const UT_RefArray<UT_VectorF>& bs,
00613 const UT_JobInfo& info
00614 ) const;
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 THREADED_METHOD5_CONST(SIM_RawField, shouldMultiThread(),
00625 solveUpperTriangularSystems,
00626 const UT_PtrArray<SIM_RawSparseMatrix*>&, ud,
00627 UT_RefArray<UT_VectorF>&, xs,
00628 const UT_PtrArray<SIM_RawSparseMatrix*>&, us,
00629 const UT_VectorF&, xc,
00630 UT_RefArray<UT_VectorF>&, ys
00631 )
00632 void solveUpperTriangularSystemsPartial(
00633 const UT_PtrArray<SIM_RawSparseMatrix*>& ud,
00634 UT_RefArray<UT_VectorF>& xs,
00635 const UT_PtrArray<SIM_RawSparseMatrix*>& us,
00636 const UT_VectorF& xc,
00637 UT_RefArray<UT_VectorF>& ys,
00638 const UT_JobInfo& info
00639 ) const;
00640
00641
00642 THREADED_METHOD2_CONST(SIM_RawField, shouldMultiThread(),
00643 incompleteCholeskyPreconditioner,
00644 const UT_VectorF &, b,
00645 UT_VectorF &, x)
00646 void incompleteCholeskyPreconditionerPartial(
00647 const UT_VectorF &b,
00648 UT_VectorF &x,
00649 const UT_JobInfo &info) const;
00650
00651
00652 THREADED_METHOD2_CONST(SIM_RawField, shouldMultiThread(),
00653 incompleteCholeskyFactorization,
00654 const SIM_RawSparseMatrix &, A,
00655 PCG_METHOD, pcgmethod)
00656 void incompleteCholeskyFactorizationPartial(
00657 const SIM_RawSparseMatrix &A,
00658 PCG_METHOD pcgmethod,
00659 const UT_JobInfo &info) const;
00660
00661
00662
00663 void enforceBoundary(SIM_FieldBoundary collisionboundary = SIM_BOUNDARY_NONE,
00664 const SIM_RawField *collision=0,
00665 const SIM_RawField *cvalue = 0);
00666 void enforceCollisionBoundary(SIM_FieldBoundary boundary,
00667 const SIM_RawField *collision,
00668 const SIM_RawField *cvalue = 0);
00669 void enforceSideBoundary(int axis, int side,
00670 SIM_FieldBoundary bound,
00671 fpreal boundaryvalue);
00672
00673 THREADED_METHOD3(SIM_RawField, shouldMultiThread(),
00674 enforceCollisionBoundaryInternal,
00675 SIM_FieldBoundary, boundary,
00676 const SIM_RawField *, collision,
00677 const SIM_RawField *, cvalue)
00678 void enforceCollisionBoundaryInternalPartial(
00679 SIM_FieldBoundary boundary,
00680 const SIM_RawField *collision,
00681 const SIM_RawField *cvalue,
00682 const UT_JobInfo &info);
00683
00684
00685
00686
00687
00688 void enforceBoundaryFlat(fpreal32 *values,
00689 const SIM_RawIndexField *collision_lookup);
00690 THREADED_METHOD2(SIM_RawField, shouldMultiThread(),
00691 enforceCollisionBoundaryFlat,
00692 fpreal32 *, values,
00693 const SIM_RawIndexField *, collision_lookup)
00694
00695 void enforceCollisionBoundaryFlatPartial(fpreal32 *values,
00696 const SIM_RawIndexField *collision_lookup,
00697 const UT_JobInfo &info);
00698 void enforceSideBoundaryFlat(fpreal32 *values,
00699 int axis, int side,
00700 SIM_FieldBoundary bound,
00701 fpreal boundval);
00702
00703
00704
00705
00706
00707
00708
00709
00710 void setBoundary(int axis, int side, SIM_FieldBoundary bound)
00711 { myBoundary[axis][side] = bound; }
00712 SIM_FieldBoundary getBoundary(int axis, int side) const
00713 { return myBoundary[axis][side]; }
00714 void setBoundaryValue(int axis, int side, fpreal v)
00715 { myBoundaryValue[axis][side] = v; }
00716 fpreal getBoundaryValue(int axis, int side) const
00717 { return myBoundaryValue[axis][side]; }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 void waveletTransform(UT_Wavelet::WAVELET_NAMES wavelettype,
00731 const SIM_RawField *field,
00732 int maxpasses = -1);
00733 void waveletInverseTransform(
00734 UT_Wavelet::WAVELET_NAMES wavelettype,
00735 const SIM_RawField *wavelet,
00736 int maxpasses = -1);
00737
00738
00739 void waveletComputePSD(const SIM_RawField *wavelet,
00740 int level);
00741
00742
00743 void waveletExtractComponent(const SIM_RawField *wavelet,
00744 int level,
00745 int component);
00746
00747 THREADED_METHOD2(SIM_RawField, shouldMultiThread(), buildFromGeo,
00748 const GEO_PrimVolume *, vol,
00749 const UT_DMatrix4 &, xform)
00750 void buildFromGeoPartial(const GEO_PrimVolume *vol,
00751 const UT_DMatrix4 &xform,
00752 const UT_JobInfo &info);
00753
00754 protected:
00755 void waveletRebuildFromVoxelArray(
00756 UT_VoxelArrayF *array,
00757 float scale);
00758
00759
00760 static fpreal applyBoundary(SIM_FieldBoundary bound, fpreal v,
00761 fpreal boundval);
00762
00763
00764
00765 static fpreal64 applyReduction(REDUCE_NAMES op,
00766 fpreal64 a, fpreal64 b,
00767 bool final);
00768
00769 static fpreal64 applyMaskedReduction(REDUCE_NAMES op,
00770 fpreal64 a, fpreal64 mask, fpreal64 b,
00771 bool final);
00772 static fpreal64 getReductionDefault(REDUCE_NAMES op);
00773
00774 THREADED_METHOD2_CONST(SIM_RawField, shouldMultiThread(), reduceOpInternal,
00775 fpreal64 *, sum,
00776 REDUCE_NAMES, op)
00777 void reduceOpInternalPartial(fpreal64 *sum, REDUCE_NAMES op, const UT_JobInfo &info) const;
00778
00779 THREADED_METHOD5_CONST(SIM_RawField, shouldMultiThread(), reduceMaskedOpInternal,
00780 fpreal64 *, sum,
00781 fpreal64 *, masktotal,
00782 REDUCE_NAMES, op,
00783 const SIM_RawField *, mask,
00784 bool, maskissdf)
00785 void reduceMaskedOpInternalPartial(fpreal64 *sum, fpreal64 *masktotal, REDUCE_NAMES op, const SIM_RawField *maskfield, bool maskissdf, const UT_JobInfo &info) const;
00786
00787 void sortAllVoxels(UT_FloatArray &voxelvalues) const;
00788 void sortAllVoxelsMasked(UT_FloatArray &voxelvalues,
00789 const SIM_RawField *maskfield,
00790 bool maskissdf) const;
00791
00792
00793 SIM_FieldSample mySample;
00794 UT_VoxelArrayF *myField;
00795
00796
00797
00798 UT_Vector3 myOrig, mySize;
00799
00800
00801 UT_Vector3 myBBoxOrig, myBBoxSize;
00802
00803 UT_Vector3 myVoxelSize;
00804 fpreal myVoxelDiameter;
00805
00806 SIM_FieldBoundary myBoundary[3][2];
00807 fpreal myBoundaryValue[3][2];
00808 };
00809
00810
00811
00812
00813
00814
00815
00816
00817 class SIM_API SIM_RawFieldCellIterator
00818 {
00819 public:
00820 SIM_RawFieldCellIterator()
00821 {
00822 myRes[0] = myRes[1] = myRes[2] = 0;
00823 rewind();
00824 }
00825 virtual ~SIM_RawFieldCellIterator()
00826 {
00827 }
00828
00829 void setArray(const SIM_RawField *field)
00830 {
00831 field->getVoxelRes(myRes[0], myRes[1], myRes[2]);
00832 rewind();
00833 }
00834
00835 void rewind()
00836 {
00837 myIdx[0] = 0;
00838 myIdx[1] = 0;
00839 myIdx[2] = 0;
00840 }
00841
00842 bool atEnd() const
00843 {
00844 return myIdx[2] >= myRes[2];
00845 }
00846
00847 void advance()
00848 {
00849 myIdx[0]++;
00850 if (myIdx[0] >= myRes[0])
00851 {
00852 myIdx[0] = 0;
00853 myIdx[1]++;
00854 if (myIdx[1] >= myRes[1])
00855 {
00856 myIdx[1] = 0;
00857 myIdx[2]++;
00858 if (myIdx[2] >= myRes[2])
00859 {
00860
00861 myIdx[2] = myRes[2];
00862 }
00863 }
00864 }
00865 }
00866
00867 int x() const { return myIdx[0]; }
00868 int y() const { return myIdx[1]; }
00869 int z() const { return myIdx[2]; }
00870 int idx(int axis) const { return myIdx[axis]; }
00871
00872
00873
00874
00875 bool isStartOfTile() const
00876 {
00877 return myIdx[0] == 0;
00878 }
00879
00880 protected:
00881 int myIdx[3];
00882 int myRes[3];
00883 };
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 #define CALL_PROBEXY(XSTEP, YSTEP, src, dst, command) \
00909 { \
00910 if ((dstsample ^ srcsample) & 4) \
00911 { \
00912 if (dstsample & 4) \
00913 { \
00914 UT_VoxelProbeAverage<fpreal32, XSTEP, YSTEP, -1> theprobe; \
00915 theprobe.setArray(src->field()); \
00916 command; \
00917 } \
00918 else \
00919 { \
00920 UT_VoxelProbeAverage<fpreal32, XSTEP, YSTEP, 1> theprobe; \
00921 theprobe.setArray(src->field()); \
00922 command; \
00923 } \
00924 } \
00925 else \
00926 { \
00927 UT_VoxelProbeAverage<fpreal32, XSTEP, YSTEP, 0> theprobe; \
00928 theprobe.setArray(src->field()); \
00929 command; \
00930 } \
00931 }
00932
00933 #define CALL_PROBEX(XSTEP, src, dst, command) \
00934 { \
00935 if ((dstsample ^ srcsample) & 2) \
00936 { \
00937 if (dstsample & 2) \
00938 { \
00939 CALL_PROBEXY(XSTEP, -1, src, dst, command); \
00940 } \
00941 else \
00942 { \
00943 CALL_PROBEXY(XSTEP, 1, src, dst, command); \
00944 } \
00945 } \
00946 else \
00947 { \
00948 CALL_PROBEXY(XSTEP, 0, src, dst, command); \
00949 } \
00950 }
00951
00952 #define CALL_VOXELPROBE(src, dst, command) \
00953 { \
00954 int dstsample, srcsample; \
00955 dstsample = dst->getSample(); \
00956 srcsample = src->getSample(); \
00957 if ((dstsample ^ srcsample) & 1) \
00958 { \
00959 if (dstsample & 1) \
00960 { \
00961 CALL_PROBEX(-1, src, dst, command); \
00962 } \
00963 else \
00964 { \
00965 CALL_PROBEX(1, src, dst, command); \
00966 } \
00967 } \
00968 else \
00969 { \
00970 CALL_PROBEX(0, src, dst, command); \
00971 } \
00972 }
00973
00974 #endif