/**************************************************************************** * IDOLib * * Interactive Deformable Objects Library * * http://idolib.sf.net * * * * Copyright(C) 2005 * * Visual Computing Lab * * ISTI - Italian National Research Council * * * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #include #include #ifndef VCG_INSIDE #define VCG_INSIDE ///this static funtion is used to see if one point is inside ///a triangular mesh or not... First parameter is a spatial indexing ///structure (eg. a grid) used to perform research operation, ///initialized with faces of the triangular mesh of type TriMeshType namespace vcg { namespace trimesh { template class Inside{ private: typedef typename FaceSpatialIndexing::CoordType CoordType; typedef typename FaceSpatialIndexing::ScalarType ScalarType; public: //return true if the point is inside the mesh static bool Is_Inside(TriMeshType &m, FaceSpatialIndexing &_g_mesh, const CoordType &test) { typedef typename TriMeshType::FaceType FaceType; typedef typename TriMeshType::ScalarType ScalarType; typedef typename TriMeshType::CoordType CoordType; const ScalarType EPSILON 0.000001; ///first test if the element is inside the bb of the mesh if (!m.bbox.IsIn(test)) return false; else { ScalarType dist; CoordType Norm,ip,nearest; FaceType *f=vcg::trimesh::GetClosestFace(m,_g_mesh,test,m.bbox.Diag(),dist,nearest,Norm,ip); //any face in the mesh assert(f!=NULL); //if the point is on the face is considered inside if ((test-nearest).Norm()<=EPSILON) return true; ///if the point is in surface of a face then is ok if ((ip.V(0)>EPSILON)&&(ip.V(1)>EPSILON)&&(ip.V(2)>EPSILON)) { if ((f->N()*(test-nearest))<0)///in this case normal direction is enought return true; else return false; } ///in this case we are not sure because ///hit an edge or a vertex then we use a ray that ///go until the barycenter of found face, ///then see normal value again else { CoordType bary=f->Barycenter(); vcg::Ray3 r; r.Set(test,(bary-test));///set origin and direction r.Normalize(); FaceType *f1=vcg::trimesh::DoRay(m,_g_mesh,r,m.bbox.Diag(),dist); if (f1==NULL) assert(0); if ((f1->N()*(test-bary))<0)///in this case normal direction is enought return true; else return false; } } } }; // end class } } #endif