110 lines
3.9 KiB
C
110 lines
3.9 KiB
C
|
|
||
|
/****************************************************************************
|
||
|
* 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 <vcg/space/ray3.h>
|
||
|
#include <vcg/space/box3.h>
|
||
|
|
||
|
#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 FaceSpatialIndexing,class TriMeshType>
|
||
|
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<TriMeshType,FaceSpatialIndexing>(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<ScalarType> r;
|
||
|
r.Set(test,(bary-test));///set origin and direction
|
||
|
r.Normalize();
|
||
|
FaceType *f1=vcg::trimesh::DoRay<TriMeshType,FaceSpatialIndexing>(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
|