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 GEO_PointTree;
00046 class GEO_PrimVolume;
00047 class GEO_PrimVolumeXform;
00048 class GU_Detail;
00049
00050 class gu_sdf_qelem;
00051
00052
00053
00054
00055
00056 enum SIM_FieldSample
00057 {
00058 SIM_SAMPLE_CENTER = 0,
00059 SIM_SAMPLE_FACEX = 1,
00060 SIM_SAMPLE_FACEY = 2,
00061 SIM_SAMPLE_EDGEXY = 3,
00062 SIM_SAMPLE_FACEZ = 4,
00063 SIM_SAMPLE_EDGEXZ = 5,
00064 SIM_SAMPLE_EDGEYZ = 6,
00065 SIM_SAMPLE_CORNER = 7
00066 };
00067
00068 enum SIM_FieldBoundary
00069 {
00070 SIM_BOUNDARY_NONE,
00071 SIM_BOUNDARY_SAME,
00072 SIM_BOUNDARY_ZERO,
00073 SIM_BOUNDARY_NEGATE,
00074 SIM_BOUNDARY_FIXED,
00075
00076 };
00077
00078 enum SIM_FieldAdvection
00079 {
00080 SIM_ADVECT_SINGLE = 0,
00081 SIM_ADVECT_TRACE = 1,
00082 SIM_ADVECT_MIDPOINT = 2
00083 };
00084
00085
00086 typedef UT_Vector3 (*sim_PointVelocity)(const UT_Vector3 &, int);
00087
00088 class SIM_API SIM_RawField
00089 {
00090 public:
00091 SIM_RawField();
00092 virtual ~SIM_RawField();
00093
00094
00095 SIM_RawField(const SIM_RawField &src);
00096
00097
00098 const SIM_RawField &operator=(const SIM_RawField &src);
00099
00100
00101
00102
00103
00104 void init(SIM_FieldSample sample,
00105 const UT_Vector3 &orig, const UT_Vector3 &size,
00106 int xres, int yres, int zres);
00107
00108
00109
00110 void init(SIM_FieldSample sample,
00111 const UT_Vector3 &orig, const UT_Vector3 &size,
00112 UT_VoxelArrayF *voxels);
00113
00114
00115
00116
00117 void getPartialRange(UT_VoxelArrayIteratorF &vit,
00118 const UT_JobInfo &info) const;
00119
00120
00121 bool shouldMultiThread() const
00122 {
00123 #ifdef CELLBE
00124 return false;
00125 #else
00126 return field()->numTiles() > 1;
00127 #endif
00128 }
00129
00130
00131
00132
00133 void match(const SIM_RawField &src);
00134 void match(const SIM_RawIndexField &src);
00135
00136
00137
00138
00139 void resample(SIM_FieldSample sample, const SIM_RawField *src);
00140
00141
00142
00143
00144
00145
00146 void getSamplePattern(SIM_FieldSample sample, int x, int y, int z,
00147 int &numsample, int *ix, int *iy, int *iz,
00148 bool clamp) const;
00149
00150
00151
00152
00153
00154
00155
00156
00157 void extrapolate(const SIM_RawField *depths, fpreal isocontour,
00158 fpreal dir, fpreal maxdist,
00159 bool clamp, fpreal clampval);
00160
00161
00162
00163
00164
00165
00166
00167 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), moveAlongCurvature,
00168 fpreal, b_val,
00169 const SIM_RawField &, source,
00170 fpreal, timestep)
00171 void moveAlongCurvaturePartial(fpreal b_val,
00172 const SIM_RawField &source,
00173 fpreal timestep,
00174 const UT_JobInfo &jobinfo);
00175
00176
00177
00178
00179 void moveAlongCurvature(fpreal amount,
00180 fpreal cflcond,
00181 int miniter, int maxiter);
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), moveAlongNormal,
00192 const SIM_RawField &, speed,
00193 const SIM_RawField &, source,
00194 fpreal, timestep)
00195 void moveAlongNormalPartial(const SIM_RawField &speed,
00196 const SIM_RawField &source,
00197 fpreal timestep, const UT_JobInfo &info);
00198
00199
00200
00201 void moveAlongNormalMidpoint(const SIM_RawField &speed,
00202 const SIM_RawField &source,
00203 fpreal timestep);
00204
00205
00206
00207
00208
00209
00210
00211 void reinitializeSignedDistance(int maxiter);
00212
00213
00214 THREADED_METHOD(SIM_RawField, shouldMultiThread(), negate)
00215 void negatePartial(const UT_JobInfo &info);
00216
00217
00218 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), scale,
00219 fpreal, scale)
00220 void scalePartial(fpreal scale, const UT_JobInfo &info);
00221
00222
00223
00224
00225 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), maximum,
00226 const SIM_RawField *, other)
00227 void maximumPartial(const SIM_RawField *other, const UT_JobInfo &info);
00228
00229 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), minimum,
00230 const SIM_RawField *, other)
00231 void minimumPartial(const SIM_RawField *other, const UT_JobInfo &jobinfo);
00232
00233
00234
00235 THREADED_METHOD1(SIM_RawField, shouldMultiThread(), average,
00236 const SIM_RawField &, other)
00237 void averagePartial(const SIM_RawField &other, const UT_JobInfo &jobinfo);
00238
00239
00240
00241
00242 THREADED_METHOD3_CONST(SIM_RawField, shouldMultiThread(), sumPerComponent,
00243 UT_DoubleArray &, result,
00244 UT_Int64Array &, activevoxels,
00245 const SIM_RawIndexField *, comp)
00246 void sumPerComponentPartial(UT_DoubleArray &result,
00247 UT_Int64Array &activevoxels,
00248 const SIM_RawIndexField *comp,
00249 const UT_JobInfo &info) const;
00250
00251
00252
00253 THREADED_METHOD2(SIM_RawField, shouldMultiThread(), addValuePerComponent,
00254 const UT_DoubleArray &, valuelist,
00255 const SIM_RawIndexField *, comp)
00256 void addValuePerComponentPartial(const UT_DoubleArray &valuelist,
00257 const SIM_RawIndexField *comp,
00258 const UT_JobInfo &info);
00259
00260
00261
00262 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), setScaleAdd,
00263 const SIM_RawField &, A,
00264 fpreal, scale,
00265 const SIM_RawField &, B)
00266 void setScaleAddPartial(const SIM_RawField &A,
00267 fpreal scale,
00268 const SIM_RawField &B, const UT_JobInfo &jobinfo);
00269
00270
00271
00272
00273 THREADED_METHOD2(SIM_RawField, shouldMultiThread(), smearedSign,
00274 const SIM_RawField &, sdf,
00275 fpreal, bandwidth)
00276 void smearedSignPartial(const SIM_RawField &sdf,
00277 fpreal bandwidth,
00278 const UT_JobInfo &info);
00279
00280
00281
00282 THREADED_METHOD(SIM_RawField, shouldMultiThread(), convertToHeaviside)
00283 void convertToHeavisidePartial(const UT_JobInfo &info);
00284
00285
00286 static fpreal toHeaviside(fpreal val, fpreal diam);
00287 static fpreal fromHeaviside(fpreal val, fpreal diam);
00288
00289 fpreal toHeaviside(fpreal val) const;
00290 fpreal fromHeaviside(fpreal val) const;
00291
00292
00293 enum REDUCE_NAMES
00294 {
00295 REDUCE_MAX,
00296 REDUCE_MIN,
00297 REDUCE_AVERAGE,
00298 REDUCE_SUM,
00299 REDUCE_SUMABS,
00300 REDUCE_SUMSQUARE,
00301 REDUCE_RMS,
00302 REDUCE_MEDIAN
00303 };
00304
00305
00306
00307
00308 fpreal reduceOp(REDUCE_NAMES op) const;
00309
00310
00311 fpreal average() const { return reduceOp(REDUCE_AVERAGE); }
00312
00313
00314
00315
00316 void localReduceOp(REDUCE_NAMES op, const UT_Vector3 &radius);
00317
00318
00319
00320 void boxBlur(float radius)
00321 {
00322 UT_Vector3 r(radius, radius, radius);
00323 localReduceOp(REDUCE_AVERAGE, r);
00324 }
00325
00326
00327
00328
00329 fpreal reduceMaskedOp(REDUCE_NAMES op,
00330 const SIM_RawField *mask, bool maskissdf) const;
00331
00332
00333
00334
00335 fpreal findProportionalValue(fpreal position,
00336 const SIM_RawField *mask, bool maskissdf) const;
00337
00338
00339
00340
00341
00342 bool isMatching(const SIM_RawField *field) const;
00343 bool isMatching(const SIM_RawIndexField *field) const;
00344
00345
00346
00347
00348 bool isAligned(const SIM_RawField *field) const;
00349 bool isAligned(const SIM_RawIndexField *field) const;
00350
00351
00352 bool hasNan() const { return field()->hasNan(); }
00353
00354
00355
00356 void testForNan() const;
00357
00358
00359 UT_VoxelArrayF *field() const { return myField; }
00360
00361
00362
00363 UT_VoxelArrayF *steal();
00364
00365 const UT_Vector3 &getOrig() const { return myOrig; }
00366 const UT_Vector3 &getSize() const { return mySize; }
00367 const UT_Vector3 &getBBoxOrig() const { return myBBoxOrig; }
00368 const UT_Vector3 &getBBoxSize() const { return myBBoxSize; }
00369 const UT_Vector3 &getVoxelSize() const { return myVoxelSize; }
00370 fpreal getVoxelDiameter() const { return myVoxelDiameter; }
00371 fpreal getVoxelVolume() const
00372 { return myVoxelSize.x()
00373 * myVoxelSize.y()
00374 * myVoxelSize.z(); }
00375
00376 SIM_FieldSample getSample() const { return mySample; }
00377
00378 int64 getMemoryUsage() const;
00379
00380
00381
00382
00383 void getVoxelRes(int &xres, int &yres, int &zres) const;
00384
00385
00386
00387
00388 fpreal getValue(UT_Vector3 pos) const;
00389
00390
00391 fpreal getCellValue(int x, int y, int z) const;
00392
00393
00394
00395 void addToCell(int x, int y, int z, fpreal v);
00396
00397
00398
00399
00400 void setCellValue(int x, int y, int z, fpreal v);
00401
00402
00403
00404 UT_Vector3 getGradient(UT_Vector3 pos) const;
00405
00406
00407
00408 UT_Vector3 getGradientAtIndex(int x, int y, int z) const;
00409
00410
00411
00412 fpreal64 getLaplacian(UT_Vector3 pos) const;
00413
00414
00415
00416 fpreal64 getLaplacianAtIndex(int x, int y, int z) const;
00417
00418
00419
00420 fpreal64 getCurvature(UT_Vector3 pos) const;
00421
00422
00423
00424
00425
00426 fpreal64 getCurvatureAtIndex(int x, int y, int z) const;
00427
00428
00429 static fpreal64 getCurvatureAtProbe(UT_VoxelProbeCubeF &probe, const UT_Vector3 &invvoxelsize);
00430
00431
00432
00433
00434
00435 fpreal64 getCurvatureTimesGradAtIndex(int x, int y, int z) const;
00436
00437
00438
00439 fpreal64 calculateHJWENO(fpreal64 v1, fpreal64 v2, fpreal64 v3, fpreal64 v4, fpreal64 v5) const;
00440
00441
00442
00443
00444
00445 fpreal64 calculateDerivative(int x, int y, int z,
00446 int axis, bool positivegradient) const;
00447
00448
00449
00450 bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
00451
00452
00453 bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
00454
00455
00456
00457
00458 bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z,
00459 fpreal &dx, fpreal &dy, fpreal &dz) const;
00460
00461
00462
00463 bool cellIndexToPos(int x, int y, int z, UT_Vector3 &pos) const;
00464 bool posToCellIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
00465
00466
00467
00468
00469
00470 static void advect(UT_Vector3 &pos,
00471 const SIM_RawField *velx,
00472 const SIM_RawField *vely,
00473 const SIM_RawField *velz, fpreal time,
00474 const SIM_RawField *collision = 0);
00475 static void advect(UT_Vector3 &pos,
00476 sim_PointVelocity getVelocity,
00477 fpreal time, fpreal voxelsize,
00478 int jobnum = 0,
00479 const SIM_RawField *collision = 0);
00480
00481
00482 static void advectMidpoint(UT_Vector3 &pos,
00483 const SIM_RawField *velx,
00484 const SIM_RawField *vely,
00485 const SIM_RawField *velz, fpreal time,
00486 const SIM_RawField *collision = 0);
00487 static void advectMidpoint(UT_Vector3 &pos,
00488 sim_PointVelocity getVelocity,
00489 fpreal time, fpreal voxelsize,
00490 int jobnum = 0,
00491 const SIM_RawField *collision = 0);
00492
00493
00494
00495 bool movePtToIso(UT_Vector3 &pos,
00496 fpreal goaliso,
00497 fpreal maxtime,
00498 fpreal tol = 1e-4) const;
00499
00500
00501
00502
00503 THREADED_METHOD7(SIM_RawField, shouldMultiThread(), advect,
00504 const SIM_RawField *, source,
00505 const SIM_RawField *, velx,
00506 const SIM_RawField *, vely,
00507 const SIM_RawField *, velz,
00508 fpreal, time,
00509 const SIM_RawField *, collision,
00510 SIM_FieldAdvection, advectmethod
00511 )
00512 void advectPartial(const SIM_RawField *source,
00513 const SIM_RawField *velx,
00514 const SIM_RawField *vely,
00515 const SIM_RawField *velz,
00516 fpreal time,
00517 const SIM_RawField *collision,
00518 SIM_FieldAdvection advectmethod,
00519 const UT_JobInfo &info);
00520
00521 THREADED_METHOD4(SIM_RawField, shouldMultiThread(),
00522 buoyancy,
00523 const SIM_RawField *, temperature,
00524 fpreal, up,
00525 fpreal, Tamb,
00526 fpreal, buoyancy)
00527 void buoyancyPartial(const SIM_RawField *temperature,
00528 fpreal up, fpreal Tamb,
00529 fpreal buoyancy,
00530 const UT_JobInfo &info);
00531
00532 enum MIX_NAMES {
00533 MIX_COPY,
00534 MIX_ADD,
00535 MIX_SUB,
00536 MIX_MUL,
00537 MIX_DIV,
00538 MIX_MAX,
00539 MIX_MIN,
00540 MIX_AVERAGE,
00541 NUM_MIX
00542 };
00543
00544
00545 static fpreal mixValues(MIX_NAMES mixtype,
00546 fpreal dest, fpreal src);
00547
00548 struct sim_particleToFieldParms
00549 {
00550 fpreal threshold, bandwidth;
00551 bool extrapolate, usemaxextrapolate;
00552 fpreal maxextrapolatedist;
00553 fpreal d_preadd, d_premul;
00554 fpreal s_preadd, s_premul;
00555 fpreal postadd, postmul;
00556 MIX_NAMES calctype;
00557
00558 bool useattrib;
00559 const char *attribname;
00560 int offset;
00561 UT_DMatrix4 xform;
00562 GEO_PrimVolumeXform *fieldxform;
00563 };
00564
00565 THREADED_METHOD3(SIM_RawField, shouldMultiThread(),
00566 applyParticles,
00567 const GU_Detail *, particles,
00568 GEO_PointTree *, pttree,
00569 sim_particleToFieldParms &, parms)
00570 void applyParticlesPartial(
00571 const GU_Detail *particles,
00572 GEO_PointTree *pttree,
00573 sim_particleToFieldParms &parms,
00574 const UT_JobInfo &info);
00575
00576 void accumulateParticles(const GU_Detail *particles,
00577 sim_particleToFieldParms &parms);
00578
00579 THREADED_METHOD5(SIM_RawField, shouldMultiThread(), advect2,
00580 const SIM_RawField *, source,
00581 sim_PointVelocity, getVelocity,
00582 fpreal, time, fpreal, voxelsize,
00583 const SIM_RawField *, collision)
00584 void advect2Partial(const SIM_RawField *source,
00585 sim_PointVelocity getVelocity,
00586 fpreal time, fpreal voxelsize,
00587 const SIM_RawField *collision,
00588 const UT_JobInfo &info);
00589
00590
00591
00592 void advectSelf(const SIM_RawField *velx,
00593 const SIM_RawField *vely,
00594 const SIM_RawField *velz,
00595 fpreal time,
00596 const SIM_RawField *collision,
00597 SIM_FieldAdvection advectmethod);
00598 void advectSelf(sim_PointVelocity getVelocity,
00599 fpreal time, fpreal voxelsize,
00600 const SIM_RawField *collision);
00601
00602
00603
00604
00605 void diffuse(fpreal diffrate,
00606 int numiter,
00607 const SIM_RawField *collision=0);
00608
00609
00610 static void diffuse(float *dstdata, const float *srcdata[3][3][3],
00611 float b, float ivsx, float ivsy, float ivsz,
00612 int tx, int ty,
00613 int max_xtile, int max_ytile,
00614 int max_xvox, int max_yvox);
00615
00616
00617 void computeConnectedComponents(UT_VoxelArray<int64> &comp, int &numcomponent) const;
00618
00619
00620
00621 THREADED_METHOD2(SIM_RawField, shouldMultiThread(), buildDivergenceFace,
00622 const SIM_VectorField *, vel,
00623 const SIM_RawField *, surface)
00624 void buildDivergenceFacePartial(const SIM_VectorField *vel,
00625 const SIM_RawField *surface,
00626 const UT_JobInfo &info);
00627
00628 enum PCG_METHOD
00629 {
00630 PCG_NONE,
00631 PCG_JACOBI,
00632 PCG_CHOLESKY,
00633 PCG_MIC
00634 };
00635
00636
00637
00638 void solvePressure(const SIM_RawField *divergence,
00639 const SIM_RawField *collision,
00640 int numiter = 20);
00641 void solvePressurePCG(const SIM_RawField &divergence,
00642 SIM_RawIndexField &index,
00643 SIM_VectorField *vel,
00644 const SIM_RawIndexField *comp = 0,
00645 const UT_IntArray *expandable = 0,
00646 const SIM_RawField *surface = 0,
00647 bool variational = true,
00648 bool ghostfluid = true,
00649 PCG_METHOD pcgmethod = PCG_MIC);
00650
00651
00652
00653
00654
00655
00656 THREADED_METHOD4(SIM_RawField, shouldMultiThread(),
00657 gaussSeidelIteration,
00658 const SIM_RawField *, B,
00659 fpreal32, weight,
00660 fpreal32, sumweight,
00661 int, parity)
00662 void gaussSeidelIterationPartial(
00663 const SIM_RawField * B,
00664 fpreal32 weight,
00665 fpreal32 sumweight,
00666 int parity,
00667 const UT_JobInfo &info);
00668
00669
00670
00671
00672 THREADED_METHOD4_CONST(SIM_RawField, shouldMultiThread(),
00673 gaussSeidelIterationFlat,
00674 fpreal32 *, A,
00675 fpreal32, weight,
00676 fpreal32, sumweight,
00677 int, parity)
00678 void gaussSeidelIterationFlatPartial(
00679 fpreal32 * A,
00680 fpreal32 weight,
00681 fpreal32 sumweight,
00682 int parity,
00683 const UT_JobInfo &info) const;
00684
00685
00686
00687
00688
00689 THREADED_METHOD4_CONST(SIM_RawField, shouldMultiThread(),
00690 gaussSeidelIterationFlat2D,
00691 fpreal32 *, A,
00692 fpreal32, weight,
00693 fpreal32, sumweight,
00694 int, parity)
00695 void gaussSeidelIterationFlat2DPartial(
00696 fpreal32 * A,
00697 fpreal32 weight,
00698 fpreal32 sumweight,
00699 int parity,
00700 const UT_JobInfo &info) const;
00701
00702
00703
00704
00705
00706
00707
00708
00709 THREADED_METHOD3_CONST(SIM_RawField, shouldMultiThread(),
00710 solveLowerTriangularSystems,
00711 const UT_PtrArray<SIM_RawSparseMatrix*>&, ld,
00712 UT_RefArray<UT_VectorF>&, ys,
00713 const UT_RefArray<UT_VectorF>&, bs
00714 )
00715 void solveLowerTriangularSystemsPartial(
00716 const UT_PtrArray<SIM_RawSparseMatrix*>& ld,
00717 UT_RefArray<UT_VectorF>& ys,
00718 const UT_RefArray<UT_VectorF>& bs,
00719 const UT_JobInfo& info
00720 ) const;
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 THREADED_METHOD5_CONST(SIM_RawField, shouldMultiThread(),
00731 solveUpperTriangularSystems,
00732 const UT_PtrArray<SIM_RawSparseMatrix*>&, ud,
00733 UT_RefArray<UT_VectorF>&, xs,
00734 const UT_PtrArray<SIM_RawSparseMatrix*>&, us,
00735 const UT_VectorF&, xc,
00736 UT_RefArray<UT_VectorF>&, ys
00737 )
00738 void solveUpperTriangularSystemsPartial(
00739 const UT_PtrArray<SIM_RawSparseMatrix*>& ud,
00740 UT_RefArray<UT_VectorF>& xs,
00741 const UT_PtrArray<SIM_RawSparseMatrix*>& us,
00742 const UT_VectorF& xc,
00743 UT_RefArray<UT_VectorF>& ys,
00744 const UT_JobInfo& info
00745 ) const;
00746
00747
00748 THREADED_METHOD2_CONST(SIM_RawField, shouldMultiThread(),
00749 incompleteCholeskyPreconditioner,
00750 const UT_VectorF &, b,
00751 UT_VectorF &, x)
00752 void incompleteCholeskyPreconditionerPartial(
00753 const UT_VectorF &b,
00754 UT_VectorF &x,
00755 const UT_JobInfo &info) const;
00756
00757
00758 THREADED_METHOD2_CONST(SIM_RawField, shouldMultiThread(),
00759 incompleteCholeskyFactorization,
00760 const SIM_RawSparseMatrix &, A,
00761 PCG_METHOD, pcgmethod)
00762 void incompleteCholeskyFactorizationPartial(
00763 const SIM_RawSparseMatrix &A,
00764 PCG_METHOD pcgmethod,
00765 const UT_JobInfo &info) const;
00766
00767
00768
00769 void enforceBoundary(SIM_FieldBoundary collisionboundary = SIM_BOUNDARY_NONE,
00770 const SIM_RawField *collision=0,
00771 const SIM_RawField *cvalue = 0);
00772 void enforceCollisionBoundary(SIM_FieldBoundary boundary,
00773 const SIM_RawField *collision,
00774 const SIM_RawField *cvalue = 0);
00775 void enforceSideBoundary(int axis, int side,
00776 SIM_FieldBoundary bound,
00777 fpreal boundaryvalue);
00778
00779 THREADED_METHOD3(SIM_RawField, shouldMultiThread(),
00780 enforceCollisionBoundaryInternal,
00781 SIM_FieldBoundary, boundary,
00782 const SIM_RawField *, collision,
00783 const SIM_RawField *, cvalue)
00784 void enforceCollisionBoundaryInternalPartial(
00785 SIM_FieldBoundary boundary,
00786 const SIM_RawField *collision,
00787 const SIM_RawField *cvalue,
00788 const UT_JobInfo &info);
00789
00790
00791
00792
00793
00794 void enforceBoundaryFlat(fpreal32 *values,
00795 const SIM_RawIndexField *collision_lookup);
00796 THREADED_METHOD2(SIM_RawField, shouldMultiThread(),
00797 enforceCollisionBoundaryFlat,
00798 fpreal32 *, values,
00799 const SIM_RawIndexField *, collision_lookup)
00800
00801 void enforceCollisionBoundaryFlatPartial(fpreal32 *values,
00802 const SIM_RawIndexField *collision_lookup,
00803 const UT_JobInfo &info);
00804 void enforceSideBoundaryFlat(fpreal32 *values,
00805 int axis, int side,
00806 SIM_FieldBoundary bound,
00807 fpreal boundval);
00808
00809
00810
00811
00812
00813
00814
00815
00816 void setBoundary(int axis, int side, SIM_FieldBoundary bound)
00817 { myBoundary[axis][side] = bound; }
00818 SIM_FieldBoundary getBoundary(int axis, int side) const
00819 { return myBoundary[axis][side]; }
00820 void setBoundaryValue(int axis, int side, fpreal v)
00821 { myBoundaryValue[axis][side] = v; }
00822 fpreal getBoundaryValue(int axis, int side) const
00823 { return myBoundaryValue[axis][side]; }
00824
00825
00826
00827
00828
00829
00830 void setAsExtrapolatedField(UT_Vector3 scale);
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843 void waveletTransform(UT_Wavelet::WAVELET_NAMES wavelettype,
00844 const SIM_RawField *field,
00845 int maxpasses = -1);
00846 void waveletInverseTransform(
00847 UT_Wavelet::WAVELET_NAMES wavelettype,
00848 const SIM_RawField *wavelet,
00849 int maxpasses = -1);
00850
00851
00852 void waveletComputePSD(const SIM_RawField *wavelet,
00853 int level);
00854
00855
00856 void waveletExtractComponent(const SIM_RawField *wavelet,
00857 int level,
00858 int component);
00859
00860 THREADED_METHOD3(SIM_RawField, shouldMultiThread(), buildFromGeo,
00861 const GEO_PrimVolume *, vol,
00862 const UT_DMatrix4 &, xform,
00863 fpreal, scale)
00864 void buildFromGeoPartial(const GEO_PrimVolume *vol,
00865 const UT_DMatrix4 &xform,
00866 fpreal scale,
00867 const UT_JobInfo &info);
00868
00869 protected:
00870 void waveletRebuildFromVoxelArray(
00871 UT_VoxelArrayF *array,
00872 float scale);
00873
00874
00875 static fpreal applyBoundary(SIM_FieldBoundary bound, fpreal v,
00876 fpreal boundval);
00877
00878 THREADED_METHOD2_CONST(SIM_RawField, shouldMultiThread(), reduceOpInternal,
00879 fpreal64 *, sum,
00880 REDUCE_NAMES, op)
00881 void reduceOpInternalPartial(fpreal64 *sum, REDUCE_NAMES op, const UT_JobInfo &info) const;
00882
00883 THREADED_METHOD5_CONST(SIM_RawField, shouldMultiThread(), reduceMaskedOpInternal,
00884 fpreal64 *, sum,
00885 fpreal64 *, masktotal,
00886 REDUCE_NAMES, op,
00887 const SIM_RawField *, mask,
00888 bool, maskissdf)
00889 void reduceMaskedOpInternalPartial(fpreal64 *sum, fpreal64 *masktotal, REDUCE_NAMES op, const SIM_RawField *maskfield, bool maskissdf, const UT_JobInfo &info) const;
00890
00891 void sortAllVoxels(UT_FloatArray &voxelvalues) const;
00892 void sortAllVoxelsMasked(UT_FloatArray &voxelvalues,
00893 const SIM_RawField *maskfield,
00894 bool maskissdf) const;
00895
00896
00897 THREADED_METHOD7(SIM_RawField, shouldMultiThread(), buildExtrapList,
00898 UT_RefArray<UT_PtrArray<gu_sdf_qelem *> > &, lists,
00899 const SIM_RawField *, depths,
00900 fpreal, isocontour,
00901 fpreal, dir,
00902 fpreal, maxdist,
00903 bool, clamp,
00904 fpreal, clampval)
00905 void buildExtrapListPartial(
00906 UT_RefArray<UT_PtrArray<gu_sdf_qelem *> > &lists,
00907 const SIM_RawField *depths,
00908 fpreal isocontour,
00909 fpreal dir, fpreal maxdist,
00910 bool clamp, fpreal clampval,
00911 const UT_JobInfo &info);
00912
00913
00914
00915 void localReduceByAxis(REDUCE_NAMES op,
00916 UT_VoxelArrayF &dst,
00917 UT_VoxelArrayF &field,
00918 UT_Vector3 radius) const;
00919
00920
00921 template <int AXIS, REDUCE_NAMES OP>
00922 void localReduceAxis(UT_VoxelArrayF &dstfield,
00923 UT_VoxelArrayF &field,
00924 float radius,
00925 const UT_JobInfo &info) const;
00926 template <int AXIS, REDUCE_NAMES OP>
00927 void localMinMaxAxis(UT_VoxelArrayF &dstfield,
00928 UT_VoxelArrayF &field,
00929 float radius,
00930 const UT_JobInfo &info) const;
00931
00932 template <int AXIS>
00933 void localReduceAxisOp(REDUCE_NAMES op,
00934 UT_VoxelArrayF &dstfield,
00935 UT_VoxelArrayF &field,
00936 float radius,
00937 const UT_JobInfo &info) const;
00938
00939 THREADED_METHOD4_CONST(SIM_RawField,
00940 field.getTileRes(1)*field.getTileRes(2) > 1,
00941 localReduceAxisX,
00942 REDUCE_NAMES, op,
00943 UT_VoxelArrayF &, dst,
00944 UT_VoxelArrayF &, field,
00945 float, radius)
00946 void localReduceAxisXPartial(
00947 REDUCE_NAMES op,
00948 UT_VoxelArrayF &dst,
00949 UT_VoxelArrayF &field,
00950 float radius,
00951 const UT_JobInfo &info) const
00952 { localReduceAxisOp<0>(op, dst, field, radius, info); }
00953
00954 THREADED_METHOD4_CONST(SIM_RawField,
00955 field.getTileRes(0)*field.getTileRes(2) > 1,
00956 localReduceAxisY,
00957 REDUCE_NAMES, op,
00958 UT_VoxelArrayF &, dst,
00959 UT_VoxelArrayF &, field,
00960 float, radius)
00961 void localReduceAxisYPartial(
00962 REDUCE_NAMES op,
00963 UT_VoxelArrayF &dst,
00964 UT_VoxelArrayF &field,
00965 float radius,
00966 const UT_JobInfo &info) const
00967 { localReduceAxisOp<1>(op, dst, field, radius, info); }
00968
00969 THREADED_METHOD4_CONST(SIM_RawField,
00970 field.getTileRes(0)*field.getTileRes(1) > 1,
00971 localReduceAxisZ,
00972 REDUCE_NAMES, op,
00973 UT_VoxelArrayF &, dst,
00974 UT_VoxelArrayF &, field,
00975 float, radius)
00976 void localReduceAxisZPartial(
00977 REDUCE_NAMES op,
00978 UT_VoxelArrayF &dst,
00979 UT_VoxelArrayF &field,
00980 float radius,
00981 const UT_JobInfo &info) const
00982 { localReduceAxisOp<2>(op, dst, field, radius, info); }
00983
00984 SIM_FieldSample mySample;
00985 UT_VoxelArrayF *myField;
00986
00987
00988
00989 UT_Vector3 myOrig, mySize;
00990
00991
00992 UT_Vector3 myBBoxOrig, myBBoxSize;
00993
00994 UT_Vector3 myVoxelSize;
00995 fpreal myVoxelDiameter;
00996
00997 SIM_FieldBoundary myBoundary[3][2];
00998 fpreal myBoundaryValue[3][2];
00999 };
01000
01001
01002
01003
01004
01005
01006
01007
01008 class SIM_API SIM_RawFieldCellIterator
01009 {
01010 public:
01011 SIM_RawFieldCellIterator()
01012 {
01013 myRes[0] = myRes[1] = myRes[2] = 0;
01014 rewind();
01015 }
01016 virtual ~SIM_RawFieldCellIterator()
01017 {
01018 }
01019
01020 void setArray(const SIM_RawField *field)
01021 {
01022 field->getVoxelRes(myRes[0], myRes[1], myRes[2]);
01023 rewind();
01024 }
01025
01026 void rewind()
01027 {
01028 myIdx[0] = 0;
01029 myIdx[1] = 0;
01030 myIdx[2] = 0;
01031 }
01032
01033 bool atEnd() const
01034 {
01035 return myIdx[2] >= myRes[2];
01036 }
01037
01038 void advance()
01039 {
01040 myIdx[0]++;
01041 if (myIdx[0] >= myRes[0])
01042 {
01043 myIdx[0] = 0;
01044 myIdx[1]++;
01045 if (myIdx[1] >= myRes[1])
01046 {
01047 myIdx[1] = 0;
01048 myIdx[2]++;
01049 if (myIdx[2] >= myRes[2])
01050 {
01051
01052 myIdx[2] = myRes[2];
01053 }
01054 }
01055 }
01056 }
01057
01058 int x() const { return myIdx[0]; }
01059 int y() const { return myIdx[1]; }
01060 int z() const { return myIdx[2]; }
01061 int idx(int axis) const { return myIdx[axis]; }
01062
01063
01064
01065
01066 bool isStartOfTile() const
01067 {
01068 return myIdx[0] == 0;
01069 }
01070
01071 protected:
01072 int myIdx[3];
01073 int myRes[3];
01074 };
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099 #define CALL_PROBEXY(XSTEP, YSTEP, src, dst, command) \
01100 { \
01101 if ((dstsample ^ srcsample) & 4) \
01102 { \
01103 if (dstsample & 4) \
01104 { \
01105 UT_VoxelProbeAverage<fpreal32, XSTEP, YSTEP, -1> theprobe; \
01106 theprobe.setArray(src->field()); \
01107 command; \
01108 } \
01109 else \
01110 { \
01111 UT_VoxelProbeAverage<fpreal32, XSTEP, YSTEP, 1> theprobe; \
01112 theprobe.setArray(src->field()); \
01113 command; \
01114 } \
01115 } \
01116 else \
01117 { \
01118 UT_VoxelProbeAverage<fpreal32, XSTEP, YSTEP, 0> theprobe; \
01119 theprobe.setArray(src->field()); \
01120 command; \
01121 } \
01122 }
01123
01124 #define CALL_PROBEX(XSTEP, src, dst, command) \
01125 { \
01126 if ((dstsample ^ srcsample) & 2) \
01127 { \
01128 if (dstsample & 2) \
01129 { \
01130 CALL_PROBEXY(XSTEP, -1, src, dst, command); \
01131 } \
01132 else \
01133 { \
01134 CALL_PROBEXY(XSTEP, 1, src, dst, command); \
01135 } \
01136 } \
01137 else \
01138 { \
01139 CALL_PROBEXY(XSTEP, 0, src, dst, command); \
01140 } \
01141 }
01142
01143 #define CALL_VOXELPROBE(src, dst, command) \
01144 { \
01145 int dstsample, srcsample; \
01146 dstsample = dst->getSample(); \
01147 srcsample = src->getSample(); \
01148 if ((dstsample ^ srcsample) & 1) \
01149 { \
01150 if (dstsample & 1) \
01151 { \
01152 CALL_PROBEX(-1, src, dst, command); \
01153 } \
01154 else \
01155 { \
01156 CALL_PROBEX(1, src, dst, command); \
01157 } \
01158 } \
01159 else \
01160 { \
01161 CALL_PROBEX(0, src, dst, command); \
01162 } \
01163 }
01164
01165 #endif