00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_MESH2PHI_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_MESH2PHI_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/geometry/t4_gpu_scan/t4_gpu_scan.h>
00013 #include <OpenTissue/core/geometry/t4_cpu_scan/t4_cpu_scan.h>
00014
00015 namespace OpenTissue
00016 {
00017 namespace grid
00018 {
00019
00032 template<typename mesh_type, typename grid_type>
00033 inline void mesh2phi(mesh_type & mesh, grid_type & phi, size_t max_resolution = 64, bool use_gpu = true)
00034 {
00035 using std::min;
00036 using std::max;
00037 using std::sqrt;
00038 using std::ceil;
00039
00040 typedef typename mesh_type::math_types math_types;
00041 typedef typename math_types::value_traits value_traits;
00042 typedef typename math_types::vector3_type vector3_type;
00043 typedef typename math_types::real_type real_type;
00044
00045
00046 real_type min_area;
00047 real_type max_area;
00048 mesh::compute_minmax_face_area(mesh,min_area,max_area);
00049
00050 assert(min_area>0 || !"mesh2phi(): Minimum face area is zero!");
00051
00052
00053
00054
00055 real_type delta = sqrt( (2.0*min_area) / 25.0 );
00056
00057 vector3_type min_coord;
00058 vector3_type max_coord;
00059
00060 mesh::compute_mesh_minimum_coord(mesh,min_coord);
00061 mesh::compute_mesh_maximum_coord(mesh,max_coord);
00062
00063
00064 size_t res_x = boost::numeric_cast<size_t>( ceil( (max_coord(0)-min_coord(0))/ delta ) - 1 );
00065 size_t res_y = boost::numeric_cast<size_t>( ceil( (max_coord(1)-min_coord(1))/ delta ) - 1 );
00066 size_t res_z = boost::numeric_cast<size_t>( ceil( (max_coord(2)-min_coord(2))/ delta ) - 1 );
00067 size_t resolution1 = max(res_x,max(res_y,res_z));
00068 std::cout << "mesh2phi(): needed resolution = " << resolution1 << std::endl;
00069
00070 size_t resolution2 = OpenTissue::math::upper_power2(resolution1);
00071 std::cout << "mesh2phi(): best power2 resolution = " << resolution2 << std::endl;
00072
00073
00074 size_t resolution3 = min(max_resolution,resolution2);
00075 std::cout << "mesh2phi(): resolution set to = " << resolution3 << std::endl;
00076
00077
00078
00079
00080
00081
00082 resolution3 = max(size_t(8),resolution3);
00083
00084 real_type dx = ( max_coord(0)-min_coord(0) ) / (resolution3-6);
00085 real_type dy = ( max_coord(1)-min_coord(1) ) / (resolution3-6);
00086 real_type dz = ( max_coord(2)-min_coord(2) ) / (resolution3-6);
00087
00088 vector3_type safety_band(dx,dy,dz);
00089 min_coord -= 2.0*safety_band;
00090 max_coord += 3.0*safety_band;
00091
00092
00093 phi.create(min_coord,max_coord, resolution3, resolution3, resolution3 );
00094
00095 vector3_type diff = max_coord - min_coord;
00096 real_type band = sqrt(diff*diff)*value_traits::half();
00097
00098 mesh::compute_angle_weighted_vertex_normals(mesh);
00099
00100 if(use_gpu)
00101 {
00102 bool gpu_done = t4_gpu_scan(
00103 mesh
00104 , band
00105 , phi
00106 );
00107
00108 if(!gpu_done)
00109 t4_cpu_scan(mesh,band,phi, t4_cpu_signed() );
00110 }
00111 else
00112 {
00113 t4_cpu_scan(mesh,band,phi, t4_cpu_signed() );
00114 }
00115
00116 std::cout << "mesh2phi(): completed phi computation" << std::endl;
00117 }
00118
00128 template<typename mesh_type, typename grid_type>
00129 inline void mesh2phi(mesh_type & mesh, grid_type & phi, double bandsize, size_t resolution, bool use_gpu = true)
00130 {
00131 using std::sqrt;
00132
00133 typedef typename mesh_type::math_types math_types;
00134 typedef typename math_types::value_traits value_traits;
00135 typedef typename math_types::vector3_type vector3_type;
00136 typedef typename math_types::real_type real_type;
00137
00138 real_type band = boost::numeric_cast<real_type>(bandsize);
00139 if(band<=value_traits::zero())
00140 throw std::invalid_argument("mesh2phi() bandsize must be positive");
00141
00142 vector3_type min_coord;
00143 vector3_type max_coord;
00144
00145 mesh::compute_mesh_minimum_coord(mesh,min_coord);
00146 mesh::compute_mesh_maximum_coord(mesh,max_coord);
00147
00148 vector3_type safety_band(band,band,band);
00149 min_coord -= safety_band;
00150 max_coord += safety_band;
00151
00152
00153 phi.create(min_coord,max_coord, resolution, resolution, resolution );
00154
00155 vector3_type diff = max_coord - min_coord;
00156 band = sqrt(diff*diff)/value_traits::two();
00157
00158 mesh::compute_angle_weighted_vertex_normals(mesh);
00159 if(use_gpu)
00160 {
00161 bool gpu_done = t4_gpu_scan(
00162 mesh
00163 , band
00164 , phi
00165 );
00166
00167 if(!gpu_done)
00168 t4_cpu_scan(mesh,band,phi, t4_cpu_signed() );
00169 }
00170 else
00171 {
00172 t4_cpu_scan(mesh,band,phi, t4_cpu_signed() );
00173 }
00174 std::cout << "mesh2phi(): completed phi computation" << std::endl;
00175 }
00176
00177 }
00178 }
00179
00180
00181 #endif