00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __SIM_FieldUtils__
00022 #define __SIM_FieldUtils__
00023
00024 #include <GU/GU_Types.h>
00025
00026
00027
00028
00029
00030 template <typename FIELDTYPE>
00031 bool
00032 SIMfieldUtilsComputeSliceWithBorder(const FIELDTYPE *field, const UT_Vector3 &totaldiv, UT_Vector3 overlapneg, UT_Vector3 overlappos, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
00033 {
00034 UT_Vector3 slice = field->getSliceDivisions();
00035
00036 if (slice.isEqual(UT_Vector3(1, 1, 1)))
00037 {
00038 minvxl = UT_Vector3(0, 0, 0);
00039 maxvxl = totaldiv;
00040
00041 return false;
00042 }
00043
00044 int sx, sy, sz;
00045 int x, y, z;
00046
00047 sx = SYSrint(slice(0));
00048 sy = SYSrint(slice(1));
00049 sz = SYSrint(slice(2));
00050
00051 if (slicenum < 0 || slicenum >= sx*sy*sz)
00052 {
00053
00054
00055 slicenum = 0;
00056 }
00057 x = slicenum % sx;
00058 slicenum -= x;
00059 slicenum /= sx;
00060 y = slicenum % sy;
00061 slicenum -= y;
00062 slicenum /= sy;
00063 z = slicenum;
00064
00065 minvxl.x() = SYSrint( x * (totaldiv.x() / sx) );
00066 maxvxl.x() = SYSrint( (x+1) * (totaldiv.x() / sx) );
00067 minvxl.y() = SYSrint( y * (totaldiv.y() / sy) );
00068 maxvxl.y() = SYSrint( (y+1) * (totaldiv.y() / sy) );
00069 minvxl.z() = SYSrint( z * (totaldiv.z() / sz) );
00070 maxvxl.z() = SYSrint( (z+1) * (totaldiv.z() / sz) );
00071
00072
00073 minvxl -= overlapneg;
00074 maxvxl += overlappos;
00075
00076 minvxl.x() = SYSclamp(minvxl.x(), 0.0, totaldiv.x());
00077 maxvxl.x() = SYSclamp(maxvxl.x(), 0.0, totaldiv.x());
00078 minvxl.y() = SYSclamp(minvxl.y(), 0.0, totaldiv.y());
00079 maxvxl.y() = SYSclamp(maxvxl.y(), 0.0, totaldiv.y());
00080 minvxl.z() = SYSclamp(minvxl.z(), 0.0, totaldiv.z());
00081 maxvxl.z() = SYSclamp(maxvxl.z(), 0.0, totaldiv.z());
00082
00083
00084 if (maxvxl.x() - minvxl.x() < 1)
00085 maxvxl.x()++;
00086 if (maxvxl.y() - minvxl.y() < 1)
00087 maxvxl.y()++;
00088 if (maxvxl.z() - minvxl.z() < 1)
00089 maxvxl.z()++;
00090
00091
00092 maxvxl.x() = SYSclamp(maxvxl.x(), 0.0, totaldiv.x());
00093 maxvxl.y() = SYSclamp(maxvxl.y(), 0.0, totaldiv.y());
00094 maxvxl.z() = SYSclamp(maxvxl.z(), 0.0, totaldiv.z());
00095
00096
00097 if (maxvxl.x() - minvxl.x() < 1)
00098 minvxl.x()--;
00099 if (maxvxl.y() - minvxl.y() < 1)
00100 minvxl.y()--;
00101 if (maxvxl.z() - minvxl.z() < 1)
00102 minvxl.z()--;
00103
00104 return true;
00105 }
00106
00107 template <typename FIELDTYPE>
00108 bool
00109 SIMfieldUtilsComputeSlice(const FIELDTYPE *field, const UT_Vector3 &totaldiv, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
00110 {
00111 return SIMfieldUtilsComputeSliceWithBorder(
00112 field, totaldiv,
00113 field->getSliceOverlapNeg(), field->getSliceOverlapPos(),
00114 slicenum, minvxl, maxvxl);
00115 }
00116
00117
00118
00119
00120 template <typename FIELDTYPE>
00121 bool
00122 SIMfieldUtilsGetSliceBorder(const FIELDTYPE *field,
00123 int a_slice, int b_slice,
00124 UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
00125 {
00126 UT_Vector3 a_min, a_max, b_min, b_max;
00127 UT_Vector3 div;
00128
00129 div = SIMfieldUtilsGetDivisionsNoSlice(field);
00130
00131 SIMfieldUtilsComputeSlice(field, div, a_slice, a_min, a_max);
00132 SIMfieldUtilsComputeSlice(field, div, b_slice, b_min, b_max);
00133
00134 UT_BoundingBox a_box(a_min, a_max), b_box(b_min, b_max);
00135
00136 if (!a_box.computeIntersection(b_box))
00137 return false;
00138
00139 minvxl = a_box.minvec();
00140 maxvxl = a_box.maxvec();
00141
00142 return true;
00143 }
00144
00145 template <typename FIELDTYPE>
00146 UT_Vector3
00147 SIMfieldUtilsGetDivisionsNoSlice(const FIELDTYPE *field)
00148 {
00149 UT_Vector3 div;
00150 int uniform;
00151
00152 uniform = field->getUniformVoxels();
00153 if (uniform)
00154 {
00155 UT_Vector3 size, searchsize;
00156 int axis, a;
00157 fpreal voxelsize;
00158 fpreal uniformdiv;
00159
00160 size = field->getRawSize();
00161 uniformdiv = field->getRawUniformDivisions();
00162
00163 searchsize = size;
00164
00165
00166
00167 axis = uniform-1;
00168
00169 if (field->getTwoDField())
00170 {
00171
00172
00173
00174 switch (field->getVoxelPlane())
00175 {
00176 case GU_PLANE_XY:
00177 if (axis == 2)
00178 axis = 0;
00179 searchsize(2) = 0.0;
00180 break;
00181 case GU_PLANE_YZ:
00182 if (axis == 0)
00183 axis = 1;
00184 searchsize(0) = 0.0;
00185 break;
00186 case GU_PLANE_XZ:
00187 if (axis == 1)
00188 axis = 2;
00189 searchsize(1) = 0.0;
00190 break;
00191 }
00192 }
00193
00194
00195 if (axis == 3)
00196 {
00197 axis = searchsize.findMaxAbsAxis();
00198 }
00199
00200 voxelsize = size(axis) / uniformdiv;
00201
00202
00203
00204
00205 if (UTequalZero(voxelsize))
00206 {
00207
00208
00209 div = uniformdiv;
00210 }
00211 else
00212 {
00213
00214 for (a = 0; a < 3; a++)
00215 {
00216 div(a) = SYSrint(size(a)/voxelsize);
00217 if (div(a) < 1.0)
00218 div(a) = 1.0;
00219 }
00220
00221
00222
00223 UT_ASSERT(!uniformdiv || UTisEqual(div(axis), uniformdiv));
00224 }
00225 }
00226 else
00227 {
00228 div = field->getRawDivisions();
00229 }
00230
00231 if (field->getTwoDField())
00232 {
00233
00234 switch (field->getVoxelPlane())
00235 {
00236 case GU_PLANE_XY:
00237 div.z() = 1.0;
00238 break;
00239 case GU_PLANE_YZ:
00240 div.x() = 1.0;
00241 break;
00242 case GU_PLANE_XZ:
00243 div.y() = 1.0;
00244 break;
00245 }
00246 }
00247
00248 return div;
00249 }
00250
00251 template <typename FIELDTYPE>
00252 UT_Vector3
00253 SIMfieldUtilsGetDivisions(const FIELDTYPE *field)
00254 {
00255 UT_Vector3 minvxl, maxvxl;
00256 UT_Vector3 div;
00257
00258 div = SIMfieldUtilsGetDivisionsNoSlice(field);
00259
00260
00261 SIMfieldUtilsComputeSlice(field, div, field->getSlice(), minvxl, maxvxl);
00262
00263 maxvxl -= minvxl;
00264
00265 return maxvxl;
00266 }
00267
00268 template <typename FIELDTYPE>
00269 UT_Vector3
00270 SIMfieldUtilsGetSizeNoSlice(const FIELDTYPE *field)
00271 {
00272 UT_Vector3 size;
00273 int uniform;
00274
00275 size = field->getRawSize();
00276
00277 uniform = field->getUniformVoxels();
00278
00279 if (uniform)
00280 {
00281 int axis;
00282 fpreal voxelsize;
00283 UT_Vector3 div;
00284 UT_Vector3 searchsize;
00285
00286 searchsize = size;
00287 axis = uniform-1;
00288
00289 if (field->getTwoDField())
00290 {
00291
00292 switch (field->getVoxelPlane())
00293 {
00294 case GU_PLANE_XY:
00295 if (axis == 2)
00296 axis = 0;
00297 searchsize(2) = 0;
00298 break;
00299 case GU_PLANE_YZ:
00300 if (axis == 0)
00301 axis = 1;
00302 searchsize(0) = 0;
00303 break;
00304 case GU_PLANE_XZ:
00305 if (axis == 1)
00306 axis = 2;
00307 searchsize(1) = 0;
00308 break;
00309 }
00310 }
00311
00312
00313 if (axis == 3)
00314 axis = searchsize.findMaxAbsAxis();
00315
00316
00317 div = SIMfieldUtilsGetDivisionsNoSlice(field);
00318
00319
00320 voxelsize = size(axis) / div(axis);
00321
00322
00323 size = voxelsize * div;
00324 }
00325
00326 return size;
00327 }
00328
00329 template <typename FIELDTYPE>
00330 UT_Vector3
00331 SIMfieldUtilsGetSize(const FIELDTYPE *field)
00332 {
00333 UT_Vector3 size;
00334 UT_Vector3 div;
00335 UT_Vector3 minvxl, maxvxl;
00336
00337 div = SIMfieldUtilsGetDivisionsNoSlice(field);
00338 size = SIMfieldUtilsGetSizeNoSlice(field);
00339
00340 if (SIMfieldUtilsComputeSlice(field, div, field->getSlice(), minvxl, maxvxl))
00341 {
00342 UT_Vector3 voxelsize;
00343
00344 voxelsize = size / div;
00345
00346
00347 maxvxl -= minvxl;
00348
00349
00350 size = maxvxl * voxelsize;
00351 }
00352
00353 return size;
00354 }
00355
00356 template <typename FIELDTYPE>
00357 UT_Vector3
00358 SIMfieldUtilsGetCenter(const FIELDTYPE *field)
00359 {
00360 UT_Vector3 size;
00361 UT_Vector3 div;
00362 UT_Vector3 minvxl, maxvxl;
00363 UT_Vector3 center;
00364
00365 div = SIMfieldUtilsGetDivisionsNoSlice(field);
00366 center = field->getRawCenter();
00367
00368 if (SIMfieldUtilsComputeSlice(field, div, field->getSlice(), minvxl, maxvxl))
00369 {
00370 UT_Vector3 voxelsize;
00371
00372 size = SIMfieldUtilsGetSizeNoSlice(field);
00373
00374 voxelsize = size / div;
00375
00376
00377 minvxl += maxvxl;
00378 minvxl *= 0.5;
00379
00380
00381 minvxl -= div / 2;
00382
00383
00384 minvxl *= voxelsize;
00385
00386 center += minvxl;
00387 }
00388
00389 return center;
00390 }
00391
00392
00393 template <typename FIELDTYPE, typename F2>
00394 void
00395 SIMfieldUtilsMatch(FIELDTYPE *field, const F2 *srcfield)
00396 {
00397 field->setUniformVoxels(srcfield->getUniformVoxels());
00398 field->setTwoDField(srcfield->getTwoDField());
00399 field->setVoxelPlane(srcfield->getVoxelPlane());
00400
00401 field->setRawDivisions(srcfield->getRawDivisions());
00402 field->setRawUniformDivisions(srcfield->getRawUniformDivisions());
00403 field->setRawSize(srcfield->getRawSize());
00404 field->setRawCenter(srcfield->getRawCenter());
00405
00406 field->setSlice(srcfield->getSlice());
00407 field->setSliceDivisions(srcfield->getSliceDivisions());
00408 field->setSliceOverlapNeg(srcfield->getSliceOverlapNeg());
00409 field->setSliceOverlapPos(srcfield->getSliceOverlapPos());
00410 }
00411
00412 #endif
00413