3 #ifndef __F3DUTIL_FIELDGROUP_H__
4 #define __F3DUTIL_FIELDGROUP_H__
9 #include <boost/foreach.hpp>
10 #include <boost/tokenizer.hpp>
11 #include <boost/thread/mutex.hpp>
12 #include <boost/mpl/vector.hpp>
13 #include <boost/mpl/for_each.hpp>
14 #include <boost/mpl/placeholders.hpp>
15 #include <boost/mpl/push_back.hpp>
16 #include <boost/mpl/transform.hpp>
17 #include <boost/fusion/mpl.hpp>
18 #include <boost/fusion/algorithm/iteration/for_each.hpp>
19 #include <boost/fusion/include/for_each.hpp>
20 #include <boost/fusion/include/as_vector.hpp>
45 namespace mpl = boost::mpl;
46 namespace ph = mpl::placeholders;
47 namespace fusion = boost::fusion;
48 namespace fusion_ro = boost::fusion::result_of;
50 typedef mpl::vector<Field3D::half, float, double>
ScalarTypes;
51 typedef mpl::vector<Field3D::V3h, Field3D::V3f, Field3D::V3d>
VectorTypes;
106 template <
int Dims_T>
112 const std::string &a_name,
113 const std::string &a_attribute,
114 Field3D::FieldRes::Vec &a_results,
115 Field3D::FieldRes::Vec &a_minResults,
116 Field3D::FieldRes::Vec &a_maxResults)
124 Field3D::Field3DInputFile &
in;
140 template <
typename T>
144 typename Field3D::Field<T>::Vec fields =
145 m_p.in.readScalarLayers<T>(m_p.name, m_p.attribute);
147 BOOST_FOREACH (
const typename Field3D::Field<T>::Ptr &ptr, fields) {
148 m_p.results.push_back(ptr);
151 typename Field3D::Field<T>::Vec minFields =
152 m_p.in.readScalarLayers<T>(m_p.name, m_p.attribute +
k_minSuffix);
154 BOOST_FOREACH (
const typename Field3D::Field<T>::Ptr &ptr, minFields) {
155 m_p.minResults.push_back(ptr);
158 typename Field3D::Field<T>::Vec maxFields =
159 m_p.in.readScalarLayers<T>(m_p.name, m_p.attribute +
k_maxSuffix);
161 BOOST_FOREACH (
const typename Field3D::Field<T>::Ptr &ptr, maxFields) {
162 m_p.maxResults.push_back(ptr);
177 template <
typename Vec_T>
180 typedef typename Vec_T::BaseType T;
183 typename Field3D::Field<Vec_T>::Vec fields =
184 m_p.in.readVectorLayers<T>(m_p.name, m_p.attribute);
186 BOOST_FOREACH (
const typename Field3D::Field<Vec_T>::Ptr &ptr, fields) {
187 m_p.results.push_back(ptr);
190 typename Field3D::Field<Vec_T>::Vec minFields =
191 m_p.in.readVectorLayers<T>(m_p.name, m_p.attribute +
k_minSuffix);
193 BOOST_FOREACH (
const typename Field3D::Field<Vec_T>::Ptr &ptr, minFields) {
194 m_p.minResults.push_back(ptr);
197 typename Field3D::Field<Vec_T>::Vec maxFields =
198 m_p.in.readVectorLayers<T>(m_p.name, m_p.attribute +
k_maxSuffix);
200 BOOST_FOREACH (
const typename Field3D::Field<Vec_T>::Ptr &ptr, maxFields) {
201 m_p.maxResults.push_back(ptr);
210 inline std::vector<V3d>
213 std::vector<V3d> result;
214 result.push_back(
V3d(box.min.x, box.min.y, box.min.z));
215 result.push_back(
V3d(box.max.x, box.min.y, box.min.z));
216 result.push_back(
V3d(box.min.x, box.max.y, box.min.z));
217 result.push_back(
V3d(box.max.x, box.max.y, box.min.z));
218 result.push_back(
V3d(box.min.x, box.min.y, box.max.z));
219 result.push_back(
V3d(box.max.x, box.min.y, box.max.z));
220 result.push_back(
V3d(box.min.x, box.max.y, box.max.z));
221 result.push_back(
V3d(box.max.x, box.max.y, box.max.z));
227 inline std::vector<V3d>
230 std::vector<V3d> result;
231 result.push_back(
V3d(0.0, 0.0, 0.0));
232 result.push_back(
V3d(1.0, 0.0, 0.0));
233 result.push_back(
V3d(0.0, 1.0, 0.0));
234 result.push_back(
V3d(1.0, 1.0, 0.0));
235 result.push_back(
V3d(0.0, 0.0, 1.0));
236 result.push_back(
V3d(1.0, 0.0, 1.0));
237 result.push_back(
V3d(0.0, 1.0, 1.0));
238 result.push_back(
V3d(1.0, 1.0, 1.0));
249 const double epsilon = std::numeric_limits<double>::epsilon() * 10.0;
251 for (
size_t dim = 0; dim < 3; ++dim) {
253 if (std::abs(ray.dir[dim]) < epsilon) {
255 if (ray.pos[dim] < box.min[dim] || ray.pos[dim] > box.max[dim]) {
259 t0 = (box.min[dim] - ray.pos[dim]) / ray.dir[dim];
260 t1 = (box.max[dim] - ray.pos[dim]) / ray.dir[dim];
302 template <
typename BaseTypeList_T,
int Dims_T>
311 typedef typename mpl::transform<
314 typedef typename mpl::transform<
317 typedef typename mpl::transform<
320 typedef typename mpl::transform<
325 typedef typename fusion_ro::as_vector<MPLDenseTypes>::type
DenseTypes;
326 typedef typename fusion_ro::as_vector<MPLSparseTypes>::type
SparseTypes;
327 typedef typename fusion_ro::as_vector<MPLMIPDenseTypes>::type
MIPDenseTypes;
368 virtual void setup(
const Field3D::FieldRes::Ptr field);
370 virtual void setup(
const Field3D::FieldRes::Vec &
fields);
373 virtual void setup(
const Field3D::FieldRes::Vec &
fields,
374 const Field3D::FieldRes::Vec &minFields,
375 const Field3D::FieldRes::Vec &maxFields);
379 int load(
const std::string &filename,
const std::string &attribute);
383 virtual size_t size()
const;
388 void sample(
const V3d &wsP,
const float wsSpotSize,
const float time,
393 void sample(
const V3d &vsP,
float *result,
bool isVs)
const;
397 float *result,
bool isVs)
const;
399 void sampleMultiple(
const size_t n,
const float *wsP,
float *result)
const;
401 void sampleMIPMultiple(
const size_t n,
const float *wsP,
const float *wsSpotSize,
402 float *result)
const;
482 template <
typename BaseTypeList_T,
int Dims_T>
484 : m_hasPrefiltMinMax(false), m_doWsBoundsOptimization(false)
489 template <
typename BaseTypeList_T,
int Dims_T>
491 (
const Field3D::FieldRes::Vec &fields)
492 : m_hasPrefiltMinMax(false), m_doWsBoundsOptimization(false)
500 template <
typename BaseTypeList_T,
int Dims_T>
509 template <
typename BaseTypeList_T,
int Dims_T>
513 m_doWsBoundsOptimization = doWsBoundsOptimization;
515 if (doWsBoundsOptimization) {
518 fusion::for_each(m_dense, op);
519 fusion::for_each(m_sparse, op);
520 fusion::for_each(m_mipDense, op);
521 fusion::for_each(m_mipSparse, op);
527 template <
typename BaseTypeList_T,
int Dims_T>
536 template <
typename BaseTypeList_T,
int Dims_T>
541 fields.push_back(field);
543 setup(fields, minFields, maxFields);
548 template <
typename BaseTypeList_T,
int Dims_T>
554 setup(fields, minFields, maxFields);
559 template <
typename BaseTypeList_T,
int Dims_T>
562 (
const Field3D::FieldRes::Vec &fields,
563 const Field3D::FieldRes::Vec &minFields,
564 const Field3D::FieldRes::Vec &maxFields)
567 m_allFields = fields;
570 for (
size_t i = 0, end = fields.size(); i < end; ++i) {
571 GrabFields op(fields[i], m_osToWs, m_valueRemapOp, m_doWsBoundsOptimization);
572 fusion::for_each(m_dense, op);
573 fusion::for_each(m_sparse, op);
574 fusion::for_each(m_mipDense, op);
575 fusion::for_each(m_mipSparse, op);
579 setupMinMax(minFields, maxFields);
582 template <
typename BaseTypeList_T,
int Dims_T>
585 (
const Field3D::FieldRes::Vec &minFields,
586 const Field3D::FieldRes::Vec &maxFields)
589 m_auxFields.insert(m_auxFields.end(), minFields.begin(), minFields.end());
590 m_auxFields.insert(m_auxFields.end(), maxFields.begin(), maxFields.end());
593 for (
size_t i = 0, end = minFields.size(); i < end; ++i) {
594 GrabFields op(minFields[i], m_osToWs, m_valueRemapOp, m_doWsBoundsOptimization);
595 fusion::for_each(m_mipDenseMin, op);
596 fusion::for_each(m_mipSparseMin, op);
599 for (
size_t i = 0, end = maxFields.size(); i < end; ++i) {
600 GrabFields op(maxFields[i], m_osToWs, m_valueRemapOp, m_doWsBoundsOptimization);
601 fusion::for_each(m_mipDenseMax, op);
602 fusion::for_each(m_mipSparseMax, op);
606 fusion::for_each(m_mipDenseMin, countMinOp);
607 fusion::for_each(m_mipDenseMax, countMaxOp);
608 fusion::for_each(m_mipSparseMin, countMinOp);
609 fusion::for_each(m_mipSparseMax, countMaxOp);
610 if (countMinOp.
count > 0 && countMaxOp.
count > 0) {
611 m_hasPrefiltMinMax =
true;
617 template <
typename BaseTypeList_T,
int Dims_T>
620 (
const std::string &filename,
const std::string &attribute)
622 using namespace Field3D;
630 const size_t sizeBeforeLoading = size();
634 std::vector<std::string> filenames;
635 filenames.push_back(filename);
637 BOOST_FOREACH (
const std::string fn, filenames) {
641 return k_missingFile;
645 std::vector<std::string> names;
648 BOOST_FOREACH (
const std::string &name, names) {
650 minResults, maxResults);
652 mpl::for_each<BaseTypeList_T>(op);
658 setup(results, minResults, maxResults);
661 return size() - sizeBeforeLoading;
666 template <
typename BaseTypeList_T,
int Dims_T>
669 (
const float resMult)
675 fusion::for_each(m_dense, op);
676 fusion::for_each(m_sparse, op);
679 fusion::for_each(m_mipDense, opMIP);
680 fusion::for_each(m_mipSparse, opMIP);
682 setupMinMax(minFields, maxFields);
687 template <
typename BaseTypeList_T,
int Dims_T>
692 fusion::for_each(m_dense, op);
693 fusion::for_each(m_sparse, op);
694 fusion::for_each(m_mipDense, op);
695 fusion::for_each(m_mipSparse, op);
701 template <
typename BaseTypeList_T,
int Dims_T>
706 fusion::for_each(m_mipDense, op);
707 fusion::for_each(m_mipSparse, op);
713 template <
typename BaseTypeList_T,
int Dims_T>
716 const float wsSpotSize,
724 Sample op(wsP, result, numHits);
725 fusion::for_each(m_dense, op);
726 fusion::for_each(m_sparse, op);
729 SampleMIP mipOp(wsP, wsSpotSize, result, numHits);
730 fusion::for_each(m_mipDense, mipOp);
731 fusion::for_each(m_mipSparse, mipOp);
738 for (
size_t i = 0; i < Dims_T; ++i) {
739 result[i] /=
static_cast<float>(numHits);
747 template <
typename BaseTypeList_T,
int Dims_T>
755 Sample op(vsP, result, numHits);
756 fusion::for_each(m_dense, op);
757 fusion::for_each(m_sparse, op);
762 template <
typename BaseTypeList_T,
int Dims_T>
771 fusion::for_each(m_dense, op);
772 fusion::for_each(m_sparse, op);
777 template <
typename BaseTypeList_T,
int Dims_T>
780 const float wsSpotSize,
786 SampleMIP op(vsP, wsSpotSize, result, numHits);
787 fusion::for_each(m_mipDense, op);
788 fusion::for_each(m_mipSparse, op);
793 template <
typename BaseTypeList_T,
int Dims_T>
797 const float *wsSpotSize,
803 fusion::for_each(m_mipDense, op);
804 fusion::for_each(m_mipSparse, op);
809 template <
typename BaseTypeList_T,
int Dims_T>
815 fusion::for_each(m_dense, op);
816 fusion::for_each(m_sparse, op);
817 fusion::for_each(m_mipDense, op);
818 fusion::for_each(m_mipSparse, op);
824 template <
typename BaseTypeList_T,
int Dims_T>
829 fusion::for_each(m_dense, op);
830 fusion::for_each(m_sparse, op);
831 fusion::for_each(m_mipDense, op);
832 fusion::for_each(m_mipSparse, op);
838 template <
typename BaseTypeList_T,
int Dims_T>
844 fusion::for_each(m_dense, op);
845 fusion::for_each(m_sparse, op);
846 fusion::for_each(m_mipDense, op);
847 fusion::for_each(m_mipSparse, op);
848 return intervals.size() > 0;
853 template <
typename BaseTypeList_T,
int Dims_T>
859 if (m_hasPrefiltMinMax) {
863 fusion::for_each(m_mipDenseMin, opMin);
864 fusion::for_each(m_mipSparseMin, opMin);
865 fusion::for_each(m_mipDenseMax, opMax);
866 fusion::for_each(m_mipSparseMax, opMax);
870 fusion::for_each(m_dense, op);
871 fusion::for_each(m_sparse, op);
874 fusion::for_each(m_mipDense, opMIP);
875 fusion::for_each(m_mipSparse, opMIP);
881 template <
typename BaseTypeList_T,
int Dims_T>
885 long long int result = 0;
887 fusion::for_each(m_dense, op);
888 fusion::for_each(m_sparse, op);
889 fusion::for_each(m_mipDense, op);
890 fusion::for_each(m_mipSparse, op);
898 template <
typename BaseTypeList_T,
int Dims_T>
905 const bool doWsBoundsOptimization)
906 : m_field(f),
m_osToWs(osToWs), m_op(op),
910 template <
typename WrapperVec_T>
914 typedef typename WrapperVec_T::value_type Wrapper_T;
915 typedef typename Wrapper_T::field_type Field_T;
916 typedef typename Field_T::Ptr FieldPtr;
919 Field3D::field_dynamic_cast<Field_T>(m_field)) {
923 Wrapper_T &entry = vec.back();
938 entry.setValueRemapOp(m_op);
955 template <
typename BaseTypeList_T,
int Dims_T>
963 template <
typename WrapperVec_T>
966 for (
size_t i = 0, end = vec.size(); i < end; ++i) {
976 template <
typename BaseTypeList_T,
int Dims_T>
984 template <
typename T>
986 { count += vec.size(); }
993 template <
typename BaseTypeList_T,
int Dims_T>
998 Field3D::FieldRes::Vec &maxFields,
1000 : m_minFields(minFields),
1001 m_maxFields(maxFields),
1006 template <
typename WrapperVec_T>
1010 typedef typename WrapperVec_T::value_type Wrapper_T;
1011 typedef typename Wrapper_T::field_type Field_T;
1012 typedef typename Field3D::MIPField<Field_T> MIPField_T;
1013 typedef typename Field_T::value_type Value_T;
1014 typedef typename Field3D::Field<Value_T>::Ptr FieldPtr;
1016 std::pair<FieldPtr, FieldPtr> result;
1017 for (
size_t i = 0, end = vec.size(); i < end; ++i) {
1018 const Field_T &f = *(vec[i].field);
1019 result = Field3D::makeMinMax<MIPField_T>(f, m_resMult, m_numThreads);
1020 m_minFields.push_back(result.first);
1021 m_maxFields.push_back(result.second);
1033 template <
typename BaseTypeList_T,
int Dims_T>
1038 Field3D::FieldRes::Vec &maxFields,
1039 const float resMult)
1040 : m_minFields(minFields),
1041 m_maxFields(maxFields),
1046 template <
typename WrapperVec_T>
1050 typedef typename WrapperVec_T::value_type Wrapper_T;
1051 typedef typename Wrapper_T::field_type MIPField_T;
1052 typedef typename MIPField_T::NestedType Field_T;
1053 typedef typename Field_T::value_type Value_T;
1054 typedef typename Field3D::Field<Value_T>::Ptr FieldPtr;
1056 std::pair<FieldPtr, FieldPtr> result;
1057 for (
size_t i = 0, end = vec.size(); i < end; ++i) {
1058 const Field_T &f = *(vec[i].field->concreteMipLevel(0));
1059 result = Field3D::makeMinMax<MIPField_T>(f, m_resMult, m_numThreads);
1060 m_minFields.push_back(result.first);
1061 m_maxFields.push_back(result.second);
1073 template <
typename BaseTypeList_T,
int Dims_T>
1078 : m_p(p), m_result(result), m_numHits(numHits)
1081 template <
typename T>
1094 template <
typename BaseTypeList_T,
int Dims_T>
1100 : m_p(p), m_wsSpotSize(wsSpotSize), m_result(result), m_numHits(numHits)
1103 template <
typename T>
1118 template <
typename BaseTypeList_T,
int Dims_T>
1124 : m_n(n), m_p(p), m_result(result), m_numHits(numHits)
1127 template <
typename T>
1141 template <
typename BaseTypeList_T,
int Dims_T>
1146 float *result,
size_t *numHits)
1147 : m_n(n), m_p(p), m_wsSpotSize(wsSpotSize), m_result(result),
1151 template <
typename T>
1155 m_result, m_numHits);
1167 template <
typename BaseTypeList_T,
int Dims_T>
1175 template <
typename T>
1178 for (
size_t field = 0, end = vec.size(); field < end; ++field) {
1185 for (
size_t i = 0; i < 8; ++i) {
1187 if (vec[field].doOsToWs) {
1190 vec[field].osToWs.multVecMatrix(osP, wsP);
1194 m_wsBounds.extendBy(wsP);
1205 template <
typename BaseTypeList_T,
int Dims_T>
1210 : m_wsRay(wsRay), m_intervals(intervals)
1217 const float worldScale)
const
1221 const float time = 0.0f;
1234 const double minLen =
min(
min(wsVoxelSize.x, wsVoxelSize.y),
1236 m_intervals.push_back(
Interval(t0, t1, minLen * worldScale));
1242 const float worldScale)
const
1246 typedef std::vector<V3d> PointVec;
1248 const float time = 0.0f;
1254 PointVec wsCorners(lsCorners.size());
1255 for (PointVec::iterator lsP = lsCorners.begin(), wsP = wsCorners.begin(),
1256 end = lsCorners.end(); lsP != end; ++lsP, ++wsP) {
1262 planes[0] =
Plane3d(wsCorners[4], wsCorners[0], wsCorners[6]);
1263 planes[1] =
Plane3d(wsCorners[1], wsCorners[5], wsCorners[3]);
1264 planes[2] =
Plane3d(wsCorners[4], wsCorners[5], wsCorners[0]);
1265 planes[3] =
Plane3d(wsCorners[2], wsCorners[3], wsCorners[6]);
1266 planes[4] =
Plane3d(wsCorners[0], wsCorners[1], wsCorners[2]);
1267 planes[5] =
Plane3d(wsCorners[5], wsCorners[4], wsCorners[7]);
1272 for (
int i = 0; i < 6; ++i) {
1275 if (p.intersectT(wsRay, t)) {
1276 if (wsRay.dir.dot(p.normal) > 0.0) {
1288 const double minLen =
min(
min(wsVoxelSize.x, wsVoxelSize.y),
1290 m_intervals.push_back(
Interval(t0, t1, minLen * worldScale));
1294 template <
typename T>
1298 for (
size_t field = 0, end = vec.size(); field < end; ++field) {
1300 Ray3d wsRay = m_wsRay;
1301 if (vec[field].doOsToWs) {
1302 vec[field].wsToOs.multVecMatrix(m_wsRay.pos, wsRay.pos);
1303 vec[field].wsToOs.multDirMatrix(m_wsRay.dir, wsRay.dir);
1310 intersectMatrixMapping(wsRay, mtx, vec[field].worldScale);
1315 intersectFrustumMapping(wsRay, f, vec[field].worldScale);
1326 template <
typename BaseTypeList_T,
int Dims_T>
1334 template <
typename T>
1347 template <
typename BaseTypeList_T,
int Dims_T>
1355 template <
typename T>
1368 template <
typename BaseTypeList_T,
int Dims_T>
1377 : m_wsBounds(
wsBounds), m_result(result), m_mode(mode)
1380 template <
typename T>
1383 if (m_mode == Min) {
1399 template <
typename BaseTypeList_T,
int Dims_T>
1407 template <
typename T>
1410 for (
size_t field = 0, end = vec.size(); field < end; ++field) {
1411 *m_memSize += vec[field].field->memSize();
1416 {
return m_memSize; }
1423 template <
typename BaseTypeList_T,
int Dims_T>
1428 : m_wsP(wsP), m_doesIntersect(false)
1431 template <
typename T>
1434 for (
size_t field = 0, end = vec.size(); field < end; ++field) {
1436 for (
size_t i = 0, end = vec.size(); i < end; ++i) {
1439 if (vec[i].doOsToWs) {
1441 vec[i].wsToOs.multVecMatrix(m_wsP, osP);
1442 vec[i].mapping->worldToVoxel(osP, vsP);
1444 vec[i].mapping->worldToVoxel(m_wsP, vsP);
1447 if (vec[i].vsBounds.intersects(vsP)) {
1448 m_doesIntersect =
true;
1455 {
return m_doesIntersect; }
1468 #endif // include guard