Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_UTIL_POLYMESH_IS_POINT_INSIDE_H
00002 #define OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_UTIL_POLYMESH_IS_POINT_INSIDE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_is_boundary.h>
00013 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_valency.h>
00014 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_compute_edge_direction.h>
00015 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_is_convex_boundary.h>
00016
00017 #include <OpenTissue/core/containers/mesh/common/util/mesh_compute_face_maximum_coord.h>
00018 #include <OpenTissue/core/containers/mesh/common/util/mesh_compute_face_minimum_coord.h>
00019 #include <OpenTissue/core/containers/mesh/common/util/mesh_compute_face_plane.h>
00020
00021 #include <OpenTissue/core/geometry/geometry_plane.h>
00022 #include <OpenTissue/core/geometry/geometry_ray.h>
00023 #include <OpenTissue/collision/collision_ray_aabb.h>
00024
00025
00026 namespace OpenTissue
00027 {
00028 namespace polymesh
00029 {
00030
00042 template<typename mesh_type,typename vector3_type>
00043 inline bool is_point_inside(mesh_type const & mesh, vector3_type const & p)
00044 {
00045 typedef typename mesh_type::math_types math_types;
00046 typedef typename math_types::real_type real_type;
00047 typedef geometry::Plane<math_types> plane_type;
00048
00049
00050 vector3_type u;
00051 vector3_type r = unit( vector3_type(0.3,0.6, 1.0) );
00052 plane_type plane;
00053
00054 int intersections = 0;
00055
00056 typename mesh_type::const_face_iterator begin = mesh.face_begin();
00057 typename mesh_type::const_face_iterator end = mesh.face_end();
00058 typename mesh_type::const_face_iterator f = begin;
00059 for(;f!=end;++f)
00060 {
00061 assert(is_convex_boundary( *f ) || !"only works on convex faces");
00062
00063 vector3_type max_coord;
00064 mesh::compute_face_maximum_coord(*f,max_coord);
00065 if(p(0) > max_coord(0))
00066 continue;
00067
00068 vector3_type min_coord;
00069 mesh::compute_face_minimum_coord(*f,min_coord);
00070 if(!OpenTissue::collision::ray_aabb(p,r,min_coord,max_coord))
00071 continue;
00072
00073 mesh::compute_face_plane( *f, plane );
00074 real_type d = plane.signed_distance(p);
00075 real_type nr = plane.n() * r;
00076
00077
00078
00079
00080
00081
00082
00083 if(nr==0 && d != 0)
00084 continue;
00085
00086 if(nr<0 && d < 0)
00087 continue;
00088
00089 if(nr>0 && d > 0)
00090 continue;
00091
00092 real_type t = -d / nr;
00093 vector3_type pp = p + r*t;
00094
00095 bool ray_inside_face = true;
00096 typename mesh_type::face_halfedge_circulator h(*f),hend;
00097 for(;h!=hend;++h)
00098 {
00099 compute_edge_direction( *h, u);
00100 vector3_type diff = pp - h->get_origin_iterator()->m_coord;
00101 if( plane.n() * cross( u , diff ) < 0)
00102 {
00103 ray_inside_face = false;
00104 break;
00105 }
00106 }
00107 if(ray_inside_face)
00108 ++intersections;
00109 }
00110 return ((intersections%2)==1);
00111 }
00112
00113 }
00114 }
00115
00116
00117 #endif