Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_UTIL_POLYMESH_COMPUTE_DISTANCE_H
00002 #define OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_UTIL_POLYMESH_COMPUTE_DISTANCE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_edge.h>
00013 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_vertex.h>
00014 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_face.h>
00015
00016 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_compute_vertex_edge_voronoi_plane.h>
00017 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_compute_edge_face_voronoi_plane.h>
00018
00019 #include <OpenTissue/core/containers/mesh/common/util/mesh_compute_face_plane.h>
00020
00021
00022 #include <OpenTissue/core/geometry/geometry_plane.h>
00023
00024 #include <cmath>
00025
00026 namespace OpenTissue
00027 {
00028 namespace polymesh
00029 {
00030
00031 template<typename mesh_type,typename vector3_type>
00032 typename vector3_type::value_type
00033 compute_distance(PolyMeshVertex<mesh_type> const & v,vector3_type const & p)
00034 {
00035 vector3_type tmp = p - v.m_coord;
00036 return std::sqrt(tmp*tmp);
00037 }
00038
00039 template<typename mesh_type,typename vector3_type>
00040 typename vector3_type::value_type
00041 compute_distance(PolyMeshFace<mesh_type> const & f, vector3_type const & p)
00042 {
00043 typedef typename mesh_type::vertex_iterator vertex_iterator;
00044 typedef typename mesh_type::face_halfedge_circulator face_halfedge_circulator;
00045 typedef typename mesh_type::halfedge_iterator halfedge_iterator;
00046 typedef typename mesh_type::face_iterator face_iterator;
00047
00048 typedef typename mesh_type::math_types math_types;
00049 typedef typename math_types::real_type real_type;
00050 typedef geometry::Plane<math_types> plane_type;
00051
00052 plane_type plane;
00053
00054 face_halfedge_circulator h(f),end;
00055 for(;h!=end;++h)
00056 {
00057 vertex_iterator v = h->get_destination_iterator();
00058 compute_vertex_edge_voronoi_plane(*v,*h,plane);
00059 if(plane.signed_distance(p) >= 0)
00060 continue;
00061
00062
00063 halfedge_iterator last = h->get_owner()->halfedge_end();
00064 halfedge_iterator search = h->get_owner()->get_halfedge_iterator(h->get_handle());
00065 bool forever = true;
00066 do
00067 {
00068 compute_vertex_edge_voronoi_plane(
00069 *(search->get_destination_iterator())
00070 , *(search)
00071 , plane);
00072
00073 if(plane.signed_distance(p)>0)
00074 {
00075 if(last==search->get_next_iterator())
00076 {
00077 return compute_distance(*(search->get_destination_iterator()),p);
00078 }
00079 last = search;
00080 search = search->get_next_iterator();
00081 continue;
00082 }
00083
00084 compute_vertex_edge_voronoi_plane(
00085 *(search->get_origin_iterator())
00086 , *(search->get_twin_iterator())
00087 , plane);
00088
00089 if(plane.signed_distance(p)>0)
00090 {
00091 if(last==search->get_prev_iterator())
00092 {
00093 return compute_distance(*(search->get_origin_iterator()),p);
00094 }
00095 last = search;
00096 search = search->get_prev_iterator();
00097 continue;
00098 }
00099
00100 vector3_type diff = p - search->get_origin_iterator()->m_coord;
00101 vector3_type u;
00102 compute_edge_direction(*search,u);
00103 u /= std::sqrt(u*u);
00104 vector3_type ortho = diff - u*(u*diff);
00105 return std::sqrt(ortho*ortho);
00106 }
00107 while(forever);
00108 }
00109
00110 mesh::compute_face_plane(f,plane);
00111 return plane.signed_distance(p);
00112 }
00113
00114 template<typename mesh_type,typename vector3_type>
00115 typename vector3_type::value_type
00116 compute_distance(PolyMeshEdge<mesh_type> const & e,vector3_type const & p)
00117 {
00118 typedef typename mesh_type::vertex_iterator vertex_iterator;
00119 typedef typename mesh_type::halfedge_iterator halfedge_iterator;
00120 typedef typename mesh_type::face_iterator face_iterator;
00121
00122 typedef typename mesh_type::math_types math_types;
00123 typedef typename math_types::real_type real_type;
00124 typedef geometry::Plane<math_types> plane_type;
00125
00126 plane_type plane;
00127
00128 halfedge_iterator h0 = e.get_halfedge0_iterator();
00129 vertex_iterator v0 = h0.get_destination_iterator();
00130 compute_vertex_edge_voronoi_plane(v0,h0,plane);
00131 if(plane.signed_distance(p)>0)
00132 return compute_distance(v0,p);
00133
00134 halfedge_iterator h1 = e.get_halfedge1_iterator();
00135 vertex_iterator v1 = h1.get_destination_iterator();
00136 compute_vertex_edge_voronoi_plane(v1,h1,plane);
00137 if(plane.signed_distance(p)>0)
00138 return compute_distance(v1,p);
00139
00140 face_iterator f0 = h0.get_face_iterator();
00141 compute_edge_face_voronoi_plane(h0,f0,plane);
00142 if(plane.signed_distance(p)>0)
00143 return compute_distance(f0,p);
00144
00145 face_iterator f1 = h1.get_face_iterator();
00146 compute_edge_face_voronoi_plane(h1,f1,plane);
00147 if(plane.signed_distance(p)>0)
00148 return compute_distance(f1,p);
00149
00150 vector3_type u = v0->m_coord - v1->m_coord;
00151 vector3_type delta = p - v1->m_coord;
00152 real_type proj = u * delta;
00153 vector3_type orto = delta - u*proj;
00154 return std::sqrt(orto*orto);
00155 }
00156
00157 }
00158 }
00159
00160
00161 #endif