Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_T4MESH_UTIL_T4MESH_MESH_COUPLING_H
00002 #define OPENTISSUE_CORE_CONTAINERS_T4MESH_UTIL_T4MESH_MESH_COUPLING_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012
00013 #include <OpenTissue/collision/spatial_hashing/spatial_hashing.h>
00014
00015 namespace OpenTissue
00016 {
00017
00018 namespace t4mesh
00019 {
00020
00021 namespace mesh_coupling
00022 {
00023
00024 template<typename surface_mesh,typename volume_mesh>
00025 class collision_policy
00026 {
00027 public:
00028
00029 typedef typename surface_mesh::vertex_type vertex_type;
00030 typedef typename volume_mesh::tetrahedron_type tetrahedron_type;
00031
00032 typedef double real_type;
00033 typedef math::Vector3<real_type> point_type;
00034
00035 typedef vertex_type* data_type;
00036 typedef tetrahedron_type query_type;
00037
00038 typedef OpenTissue::spatial_hashing::GridHashFunction hash_function;
00039 typedef OpenTissue::spatial_hashing::Grid< point_type, math::Vector3<int>, data_type, hash_function> hash_grid;
00040
00041 class result_type
00042 {
00043 public:
00044 vertex_type * m_data;
00045 tetrahedron_type * m_query;
00046 real_type m_w0;
00047 real_type m_w1;
00048 real_type m_w2;
00049 real_type m_w3;
00050 };
00051
00052 typedef std::list<result_type> result_container;
00053
00054 public:
00055
00056 point_type position(data_type const & data) const
00057 {
00058 return data->m_coord;
00059 }
00060
00061 point_type min_coord(query_type const & query) const
00062 {
00063 using std::min;
00064
00065 point_type & p0 = query.i()->m_coord;
00066 point_type & p1 = query.j()->m_coord;
00067 point_type & p2 = query.k()->m_coord;
00068 point_type & p3 = query.m()->m_coord;
00069 return min( p0, min( p1 , min( p2, p3) ) );
00070 }
00071
00072 point_type max_coord(query_type const & query) const
00073 {
00074 using std::max;
00075
00076 point_type & p0 = query.i()->m_coord;
00077 point_type & p1 = query.j()->m_coord;
00078 point_type & p2 = query.k()->m_coord;
00079 point_type & p3 = query.m()->m_coord;
00080 return max( p0, max( p1 , max( p2, p3) ) );
00081 }
00082
00083 void reset(result_container & results) { results.clear(); };
00084 void report(data_type const & data, query_type const & query,result_container & results)
00085 {
00086
00087 if(data->m_tag == 1)
00088 return;
00089
00090 point_type & pi = query.i()->m_coord;
00091 point_type & pj = query.j()->m_coord;
00092 point_type & pk = query.k()->m_coord;
00093 point_type & pm = query.m()->m_coord;
00094 point_type & p = data->m_coord;
00095
00096 real_type delta = 10e-5;
00097 real_type lower = - delta;
00098 real_type upper = 1.+ delta;
00099 result_type result;
00100 OpenTissue::geometry::barycentric_algebraic(pi,pj,pk,pm,p,result.m_w0,result.m_w1,result.m_w2,result.m_w3);
00101 if(
00102 (result.m_w0>lower)&&(result.m_w0<upper)
00103 &&
00104 (result.m_w1>lower)&&(result.m_w1<upper)
00105 &&
00106 (result.m_w2>lower)&&(result.m_w2<upper)
00107 &&
00108 (result.m_w3>lower)&&(result.m_w3<upper)
00109 )
00110 {
00111 data->m_tag = 1;
00112 result.m_data = const_cast<vertex_type*>( data );
00113 result.m_query = const_cast<tetrahedron_type*>( &query );
00114 results.push_back( result );
00115 return;
00116 }
00117 }
00118 };
00119
00129 template<typename surface_mesh, typename volume_mesh, typename point_container,typename index_container>
00130 void bind_surface (surface_mesh & M,volume_mesh & V,point_container & barycentric,index_container & bind_indices)
00131 {
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 typedef collision_policy<surface_mesh,volume_mesh> policy;
00187 typedef OpenTissue::spatial_hashing::PointDataQuery<typename policy::hash_grid, policy> point_query_type;
00188 typename policy::result_container results;
00189 point_query_type point_query;
00190 point_query.auto_init_settings(V.tetrahedron_begin(),V.tetrahedron_end());
00191
00192 mesh::clear_vertex_tags(M);
00193
00194 std::vector<typename surface_mesh::vertex_type*> vertex_ptr_container(M.size_vertices());
00195 unsigned int i = 0;
00196 for(typename surface_mesh::vertex_iterator v= M.vertex_begin();v!=M.vertex_end();++v,++i)
00197 {
00198 vertex_ptr_container[i] = &(*v);
00199 }
00200
00201 point_query(
00202 vertex_ptr_container.begin()
00203 , vertex_ptr_container.end()
00204 , V.tetrahedron_begin()
00205 , V.tetrahedron_end()
00206 , results
00207 , typename point_query_type::all_tag()
00208 );
00209
00210 unsigned int size = static_cast<unsigned int>( results.size() );
00211 barycentric.resize(size);
00212 bind_indices.resize(size);
00213 typename policy::result_container::iterator Rbegin = results.begin();
00214 typename policy::result_container::iterator Rend = results.end();
00215 for(typename policy::result_container::iterator R = Rbegin;R!=Rend;++R)
00216 {
00217 unsigned int i = static_cast<unsigned int>( R->m_data->get_handle().get_idx() );
00218
00219 barycentric[i](0) = R->m_w1;
00220 barycentric[i](1) = R->m_w2;
00221 barycentric[i](2) = R->m_w3;
00222 bind_indices[i] = R->m_query->idx();
00223 }
00224 };
00225
00238 template<typename surface_mesh, typename volume_mesh, typename point_container,typename index_container>
00239 void update_surface (
00240 surface_mesh & M,
00241 volume_mesh & V,
00242 point_container const & barycentric,
00243 index_container const & bind_info
00244 )
00245 {
00246 typename surface_mesh::vertex_iterator begin = M.vertex_begin();
00247 typename surface_mesh::vertex_iterator end = M.vertex_end();
00248
00249 typedef typename volume_mesh::tetrahedron_iterator tetrahedron_iterator;
00250 typedef typename volume_mesh::node_type node_type;
00251 typedef typename node_type::real_type real_type;
00252 typedef typename node_type::vector3_type vector3_type;
00253
00254 for( typename surface_mesh::vertex_iterator v = begin; v!=end; ++v)
00255 {
00256 unsigned int i = static_cast<unsigned int>( v->get_handle().get_idx() );
00257 tetrahedron_iterator T = V.tetrahedron( bind_info[i] );
00258
00259 real_type w1 = barycentric[i](0);
00260 real_type w2 = barycentric[i](1);
00261 real_type w3 = barycentric[i](2);
00262 real_type w0 = 1 - w1 - w2 - w3;
00263
00264 vector3_type & p0 = T->i()->m_coord;
00265 vector3_type & p1 = T->j()->m_coord;
00266 vector3_type & p2 = T->k()->m_coord;
00267 vector3_type & p3 = T->m()->m_coord;
00268 v->m_coord = p0*w0 + p1*w1 + p2*w2 + p3*w3;
00269
00270 }
00271 };
00272
00273 }
00274
00275 }
00276
00277 }
00278
00279
00280 #endif