13 #ifndef __SIM_FieldUtils__
14 #define __SIM_FieldUtils__
23 namespace SIM {
namespace FieldUtils
25 template<
typename Functor>
29 for (
exint i = start[0]; i < end[0]; ++i)
30 for (
exint j = start[1];
j < end[1]; ++
j)
31 for (
exint k = start[2]; k < end[2]; ++k)
47 return (*field.
field())(cell[0], cell[1], cell[2]);
61 return (*field.
field())(cell[0], cell[1], cell[2]);
93 --adjacent_cell[axis];
97 ++adjacent_cell[axis];
100 return adjacent_cell;
116 for (
int axis_offset : {0,1})
118 if (edge_index & (1 << axis_offset))
120 int localAxis = (edge_axis + 1 + axis_offset) % 3;
139 for (
int axis : {0,1,2})
141 if (node_index & (1 << axis))
168 const int edge_axis,
const int direction)
170 UT_ASSERT_P(face_axis >= 0 && face_axis < 3 && edge_axis >= 0 && edge_axis < 3);
177 int axis_offset = 3 - face_axis - edge_axis;
195 for (
int axis_offset : {0,1})
197 if (node_index & (1 << axis_offset))
199 int local_axis = (face_axis + 1 + axis_offset) % 3;
210 const int face_axis,
const int direction)
212 UT_ASSERT_P(face_axis >= 0 && face_axis < 3 && edge_axis >= 0 && edge_axis < 3);
218 int axis_offset = 3 - face_axis - edge_axis;
235 for (
int axis_offset : {0,1})
237 if (!(cell_index & (1 << axis_offset)))
239 int local_axis = (edge_axis + 1 + axis_offset) % 3;
256 for (
int axis_offset : {0,1})
258 if (!(face_index & (1 << axis_offset)))
260 int local_axis = (face_axis + 1 + axis_offset) % 3;
275 for (
int axis : {0,1,2})
277 if (!(cell_index & (1 << axis)))
309 if (slicenum < 0 || slicenum >= sx*sy*sz)
323 minvxl.
x() =
SYSrint( x * (totaldiv.
x() / sx) );
324 maxvxl.
x() =
SYSrint( (x+1) * (totaldiv.
x() / sx) );
325 minvxl.
y() =
SYSrint( y * (totaldiv.
y() / sy) );
326 maxvxl.
y() =
SYSrint( (y+1) * (totaldiv.
y() / sy) );
327 minvxl.
z() =
SYSrint( z * (totaldiv.
z() / sz) );
328 maxvxl.
z() =
SYSrint( (z+1) * (totaldiv.
z() / sz) );
331 minvxl -= overlapneg;
332 maxvxl += overlappos;
334 minvxl.
x() =
SYSclamp(minvxl.
x(), 0.0, totaldiv.
x());
335 maxvxl.
x() =
SYSclamp(maxvxl.
x(), 0.0, totaldiv.
x());
336 minvxl.
y() =
SYSclamp(minvxl.
y(), 0.0, totaldiv.
y());
337 maxvxl.
y() =
SYSclamp(maxvxl.
y(), 0.0, totaldiv.
y());
338 minvxl.
z() =
SYSclamp(minvxl.
z(), 0.0, totaldiv.
z());
339 maxvxl.
z() =
SYSclamp(maxvxl.
z(), 0.0, totaldiv.
z());
342 if (maxvxl.
x() - minvxl.
x() < 1)
344 if (maxvxl.
y() - minvxl.
y() < 1)
346 if (maxvxl.
z() - minvxl.
z() < 1)
350 maxvxl.
x() =
SYSclamp(maxvxl.
x(), 0.0, totaldiv.
x());
351 maxvxl.
y() =
SYSclamp(maxvxl.
y(), 0.0, totaldiv.
y());
352 maxvxl.
z() =
SYSclamp(maxvxl.
z(), 0.0, totaldiv.
z());
355 if (maxvxl.
x() - minvxl.
x() < 1)
357 if (maxvxl.
y() - minvxl.
y() < 1)
359 if (maxvxl.
z() - minvxl.
z() < 1)
365 template <
typename FIELDTYPE>
369 UT_Vector3 slice = field->getSliceDivisions();
375 template <
typename FIELDTYPE>
381 field->getSliceOverlapNeg(), field->getSliceOverlapPos(),
382 slicenum, minvxl, maxvxl);
388 template <
typename FIELDTYPE>
391 int a_slice,
int b_slice,
404 if (!a_box.computeIntersection(b_box))
407 minvxl = a_box.minvec();
408 maxvxl = a_box.maxvec();
413 template <
typename FIELDTYPE>
420 uniform = field->getUniformVoxels();
428 size = field->getRawSize();
429 uniformdiv = field->getRawUniformDivisions();
437 if (field->getTwoDField())
442 switch (field->getVoxelPlane())
471 voxelsize = field->getRawDivisionSize();
475 voxelsize =
size(axis) / uniformdiv;
491 for (a = 0; a < 3; a++)
507 div = field->getRawDivisions();
510 if (field->getTwoDField())
513 switch (field->getVoxelPlane())
530 template <
typename FIELDTYPE>
547 template <
typename FIELDTYPE>
554 size = field->getRawSize();
556 uniform = field->getUniformVoxels();
568 if (field->getTwoDField())
571 switch (field->getVoxelPlane())
600 voxelsize = field->getRawDivisionSize();
602 voxelsize =
size(axis) /
div(axis);
605 size = voxelsize *
div;
623 template <
typename FIELDTYPE>
638 voxelsize = size /
div;
644 size = maxvxl * voxelsize;
650 template <
typename FIELDTYPE>
660 center = field->getRawCenter();
668 voxelsize = size /
div;
687 template <
typename FIELDTYPE,
typename F2>
691 field->setUniformVoxels(srcfield->getUniformVoxels());
692 field->setTwoDField(srcfield->getTwoDField());
693 field->setVoxelPlane(srcfield->getVoxelPlane());
695 field->setRawDivisions(srcfield->getRawDivisions());
696 field->setRawDivisionSize(srcfield->getRawDivisionSize());
697 field->setRawUniformDivisions(srcfield->getRawUniformDivisions());
698 field->setRawSize(srcfield->getRawSize());
699 field->setRawCenter(srcfield->getRawCenter());
701 field->setSlice(srcfield->getSlice());
702 field->setSliceDivisions(srcfield->getSliceDivisions());
703 field->setSliceOverlapNeg(srcfield->getSliceOverlapNeg());
704 field->setSliceOverlapPos(srcfield->getSliceOverlapPos());
707 srcfield->getPositionPath(pospath);
708 field->setPositionPath(pospath);
712 field->updateTotalVoxels();
714 field->setVoxelSize(srcfield->getVoxelSize());
732 for (
int i = 0; i < 3; i++)
739 for (
int i = 0; i < 3; i++)
740 for (
int j = 0;
j < 3;
j++)
744 template <
typename RAWFIELD>
747 const char *address,
int port,
751 int offx,
int offy,
int offz,
758 int offx,
int offy,
int offz,
766 if((offx & TILEMASK) == 0 && (offy & TILEMASK) == 0
767 && (offz & TILEMASK) == 0)
769 offx >> TILEBITS, offy >> TILEBITS, offz >> TILEBITS);
781 olddivvec, newdivvec,
782 field->getSliceDivisions(),
783 field->getSliceOverlapNeg(),
784 field->getSliceOverlapPos());
793 int offx,
int offy,
int offz,
801 if((offx & TILEMASK) == 0 && (offy & TILEMASK) == 0
802 && (offz & TILEMASK) == 0)
804 offx >> TILEBITS, offy >> TILEBITS, offz >> TILEBITS);
816 olddivvec, newdivvec,
817 field->getSliceDivisions(),
818 field->getSliceOverlapNeg(),
819 field->getSliceOverlapPos());
827 int offx,
int offy,
int offz,
833 for (
int i = 0; i < 3; i++)
837 if((offx & TILEMASK) == 0 && (offy & TILEMASK) == 0
838 && (offz & TILEMASK) == 0)
840 offx >> TILEBITS, offy >> TILEBITS, offz >> TILEBITS);
852 olddivvec, newdivvec,
853 field->getSliceDivisions(),
854 field->getSliceOverlapNeg(),
855 field->getSliceOverlapPos());
864 int offx,
int offy,
int offz,
870 for (
int i = 0; i < 3; i++)
871 for (
int j = 0;
j < 3;
j++)
875 if((offx & TILEMASK) == 0 && (offy & TILEMASK) == 0
876 && (offz & TILEMASK) == 0)
878 *raw[i*3+
j]->fieldNC(), offx >> TILEBITS, offy >> TILEBITS,
892 olddivvec, newdivvec,
893 field->getSliceDivisions(),
894 field->getSliceOverlapNeg(),
895 field->getSliceOverlapPos());
902 template <
typename FIELDTYPE>
914 typename FIELDTYPE::rawfield_type *oldfields[9];
916 int newdiv[3], olddiv[3], uniformdiv, axis;
919 voxelsize = field->getVoxelSize();
931 oldcenter = field->getRawCenter();
950 oldoffset = oldcenter - oldsize/2.0f;
956 newbot = center - size/2;
957 newtop = center + size/2;
965 newtop.
x() =
SYSrint(newtop.
x() + 0.0001);
966 newtop.
y() =
SYSrint(newtop.
y() + 0.0001);
967 newtop.
z() =
SYSrint(newtop.
z() + 0.0001);
968 newbot.
x() =
SYSrint(newbot.
x() - 0.0001);
969 newbot.
y() =
SYSrint(newbot.
y() - 0.0001);
970 newbot.
z() =
SYSrint(newbot.
z() - 0.0001);
978 newcenter = (newbot + newtop) / 2;
979 newsize = newtop - newbot;
983 newdiv[0] =
SYSrint(newsize.
x()/voxelsize.
x());
984 newdiv[1] =
SYSrint(newsize.
y()/voxelsize.
y());
985 newdiv[2] =
SYSrint(newsize.
z()/voxelsize.
z());
992 newcenter.
x() -= voxelsize.
x()/2;
997 newcenter.
y() -= voxelsize.
y()/2;
1002 newcenter.
z() -= voxelsize.
z()/2;
1007 newsize.
x() = newdiv[0] * voxelsize.
x();
1008 newsize.
y() = newdiv[1] * voxelsize.
y();
1009 newsize.
z() = newdiv[2] * voxelsize.
z();
1012 if (field->getTwoDField())
1014 switch (field->getVoxelPlane())
1017 newcenter.
z() = oldcenter.
z();
1020 newcenter.
x() = oldcenter.
x();
1023 newcenter.
y() = oldcenter.
y();
1029 if (oldcenter.
isEqual(newcenter) &&
1030 olddiv[0] == newdiv[0] &&
1031 olddiv[1] == newdiv[1] &&
1032 olddiv[2] == newdiv[2])
1041 field->setRawDivisions(
UT_Vector3(newdiv[0], newdiv[1], newdiv[2]));
1043 uniformdiv = newdiv[0];
1044 axis = field->getUniformVoxels()-1;
1047 searchsize = newsize;
1048 if (field->getTwoDField())
1050 switch (field->getVoxelPlane())
1055 searchsize(2) = 0.0;
1060 searchsize(0) = 0.0;
1065 searchsize(1) = 0.0;
1077 if (axis >= 0 && axis < 3)
1078 uniformdiv = newdiv[axis];
1080 field->setRawUniformDivisions(uniformdiv);
1085 if (snapcenter.
isEqual(newcenter) &&
1088 newcenter = snapcenter;
1092 snapcenter = newcenter;
1096 field->setCenter(newcenter);
1098 field->setRawSize(newsize);
1106 offset = (newcenter - newsize/2) - (oldcenter - oldsize / 2);
1107 offset /= voxelsize;
1115 offset += newslicemin - oldslicemin;
1117 voxeloffset[0] =
SYSrint(offset.x());
1118 voxeloffset[1] =
SYSrint(offset.y());
1119 voxeloffset[2] =
SYSrint(offset.z());
1127 olddivvec, newdivvec,
1130 field->updateTotalVoxels();
1132 field->pubHandleModification();
1134 field->setVoxelSize(voxelsize);
1137 template <
typename FIELDTYPE>
1142 const char *address,
1145 bool snapvalid =
false;
1148 keepdata, address, port,
1149 snapvalid, snapsize, snapcenter);
1158 template <
typename FIELDTYPE1,
typename FIELDTYPE2>
1162 if (field1->getVoxelSize() == field2->getVoxelSize())
1167 UT_Vector3 off = (origin2 - origin1) / field1->getVoxelSize();
void SIMfieldUtilsStealFields(SIM_RawIndexField **raw, SIM_IndexField *field)
SYS_FORCE_INLINE UT_Vector3I cellToNodeMap(const UT_Vector3I &cell, const int node_index)
void SIMfieldUtilsResizeKeepDataAndSnap(FIELDTYPE *field, UT_Vector3 size, UT_Vector3 center, bool keepdata, const char *address, int port, bool &snapvalid, UT_Vector3 &snapsize, UT_Vector3 &snapcenter)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
GA_API const UT_StringHolder div
int findMaxAbsAxis() const
These allow you to find out what indices to use for different axes.
const UT_VoxelArrayI * field() const
SYS_FORCE_INLINE UT_Vector3I cellToEdgeMap(const UT_Vector3I &cell, const int edge_axis, const int edge_index)
SIM_RawField * stealField(int i, int j)
void setValue(UT_Vector3I index, T value)
SIM_RawField * stealField(int axis)
void forEachVoxelRange(const UT_Vector3I &start, const UT_Vector3I &end, const Functor &f)
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
SYS_FORCE_INLINE UT_Vector3I faceToCellMap(const UT_Vector3I &face, const int axis, const int direction)
UT_Vector3T< float > UT_Vector3
GLdouble GLdouble GLdouble z
UT_Vector3 SIMfieldUtilsGetSizeNoSlice(const FIELDTYPE *field)
constexpr SYS_FORCE_INLINE T & z() noexcept
const SIM_RawField * getField(int axis) const
Retrieve raw field.
UT_VoxelArrayF * fieldNC() const
GLboolean GLboolean GLboolean GLboolean a
This class holds a three dimensional scalar field.
UT_Vector3 SIMfieldUtilsGetDivisionsNoSlice(const FIELDTYPE *field)
void copyWithOffset(const UT_VoxelArray< T > &src, int offx, int offy, int offz)
UT_Vector3T< int64 > UT_Vector3I
void SIMfieldUtilsResizeKeepData(FIELDTYPE *field, UT_Vector3 size, UT_Vector3 center, bool keepdata, const char *address, int port)
SYS_FORCE_INLINE UT_Vector3I faceToEdgeMap(const UT_Vector3I &face, const int face_axis, const int edge_axis, const int direction)
SYS_FORCE_INLINE UT_Vector3I edgeToFaceMap(const UT_Vector3I &edge, const int edge_axis, const int face_axis, const int direction)
bool SIMfieldUtilsComputeSliceWithBorder(const UT_Vector3 &slice, const UT_Vector3 &totaldiv, UT_Vector3 overlapneg, UT_Vector3 overlappos, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
UT_Vector3 SIMfieldUtilsGetSize(const FIELDTYPE *field)
SIM_RawIndexField * stealField()
SYS_FORCE_INLINE void setFieldValue(SIM_RawField &field, const UT_Vector3I &cell, fpreal32 value)
void moveTilesWithOffset(UT_VoxelArray< T > &src, int tileoffx, int tileoffy, int tileoffz)
void SIMfieldUtilsCopyWithOffset(SIM_IndexField *field, SIM_RawIndexField **raw, int offx, int offy, int offz, bool keepdata, UT_Vector3 olddivvec, UT_Vector3 newdivvec, const char *address, int port)
void SIMfieldUtilsMatch(FIELDTYPE *field, const F2 *srcfield)
SYS_FORCE_INLINE UT_Vector3I cellToCellMap(const UT_Vector3I &cell, const int axis, const int direction)
UT_Vector3 SIMfieldUtilsGetDivisions(const FIELDTYPE *field)
SYS_FORCE_INLINE UT_Vector3I nodeToCellMap(const UT_Vector3I &node, const int cell_index)
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
SYS_FORCE_INLINE fpreal32 getFieldValue(const SIM_RawField &field, const UT_Vector3I &cell)
void SIMfieldUtilsExchangeFields(const char *address, int port, RAWFIELD *dest, RAWFIELD *src, int slicenum, int offx, int offy, int offz, UT_Vector3 olddiv, UT_Vector3 newdiv, UT_Vector3 slicediv, UT_Vector3 overlapneg, UT_Vector3 overlappos)
SIM_RawField * stealField()
This class holds a three dimensional tensor field.
bool SIMfieldUtilsGetSliceBorder(const FIELDTYPE *field, int a_slice, int b_slice, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
fpreal32 SYSrint(fpreal32 val)
UT_Vector3 SIMfieldUtilsGetCenter(const FIELDTYPE *field)
SYS_FORCE_INLINE UT_Vector3I faceToNodeMap(const UT_Vector3I &face, const int face_axis, const int node_index)
bool SYSequalZero(const UT_Vector3T< T > &v)
bool SIMfieldUtilsComputeSlice(const FIELDTYPE *field, const UT_Vector3 &totaldiv, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
const SIM_RawField * getField() const
Retrieve raw field.
constexpr SYS_FORCE_INLINE bool isEqual(const UT_Vector3T &b, const T tolerance=SYS_FTOLERANCE) const noexcept
SYS_FORCE_INLINE bool UTisstring(const char *s)
SYS_FORCE_INLINE UT_Vector3I cellToFaceMap(const UT_Vector3I &cell, const int axis, const int direction)
SYS_FORCE_INLINE UT_Vector3I edgeToCellMap(const UT_Vector3I &edge, const int edge_axis, const int cell_index)
const SIM_RawIndexField * getField() const
Retrieve raw field.
This class holds a three dimensional scalar field.
UT_VoxelArrayI * fieldNC() const
bool SIMfieldUtilsIsColocated(const FIELDTYPE1 *field1, const FIELDTYPE2 *field2, UT_Vector3I &offset)
SYS_FORCE_INLINE UT_Vector3I nodeToFaceMap(const UT_Vector3I &node, const int face_axis, const int face_index)
constexpr SYS_FORCE_INLINE T & y() noexcept
bool SYSisEqual(const UT_Vector2T< T > &a, const UT_Vector2T< T > &b, S tol=SYS_FTOLERANCE)
Componentwise equality.
const SIM_RawField * getField(int i, int j) const
Retrieve raw field.
This class holds a three dimensional vector field.
UT_VoxelArrayF UT_VoxelArrayF & field
constexpr SYS_FORCE_INLINE T & x() noexcept