added closest face function which returns also barycentric coordinates and the interpolated normal for the closest point.

fixed Inside class for checking if a point is inside a mesh
minor fixes
This commit is contained in:
Luigi Malomo 2014-07-26 14:44:59 +00:00
parent 2a389bd83d
commit 2e5ac741a8
4 changed files with 56 additions and 38 deletions

View File

@ -123,20 +123,39 @@ namespace vcg {
return (0);
}
template <class MESH, class GRID>
typename MESH::FaceType * GetClosestFaceBase( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
const typename GRID::ScalarType _maxDist,typename GRID::ScalarType & _minDist,
typename GRID::CoordType &_closestPt)
{
typedef typename GRID::ScalarType ScalarType;
typedef Point3<ScalarType> Point3x;
typedef FaceTmark<MESH> MarkerFace;
MarkerFace mf;
mf.SetMesh(&mesh);
vcg::face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
_minDist=_maxDist;
return (gr.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
}
template <class MESH, class GRID>
typename MESH::FaceType * GetClosestFaceBase( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
const typename GRID::ScalarType _maxDist,typename GRID::ScalarType & _minDist,
typename GRID::CoordType &_closestPt)
{
typedef typename GRID::ScalarType ScalarType;
typedef Point3<ScalarType> Point3x;
typedef FaceTmark<MESH> MarkerFace;
MarkerFace mf;
mf.SetMesh(&mesh);
vcg::face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
_minDist=_maxDist;
return (gr.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
}
template <class MESH, class GRID>
typename MESH::FaceType * GetClosestFaceBase( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
const typename GRID::ScalarType _maxDist,typename GRID::ScalarType & _minDist,
typename GRID::CoordType &_closestPt, typename GRID::CoordType & _normf,
typename GRID::CoordType & _ip)
{
typedef typename GRID::ScalarType ScalarType;
typename MESH::FaceType * f = GetClosestFaceBase(mesh, gr, _p, _maxDist, _minDist, _closestPt);
if(_maxDist> ScalarType(fabs(_minDist)))
{
// normal computed with trilinear interpolation
InterpolationParameters<typename MESH::FaceType,typename MESH::ScalarType>(*f,f->N(),_closestPt, _ip);
_normf = (f->V(0)->cN())*_ip[0]+
(f->V(1)->cN())*_ip[1]+
(f->V(2)->cN())*_ip[2];
}
return f;
}
template <class MESH, class GRID>
typename MESH::FaceType * GetClosestFaceEP( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,

View File

@ -37,15 +37,10 @@ compiling error resolved
****************************************************************************/
#ifndef __VCG_TRIMESH_INSIDE
#define __VCG_TRIMESH_INSIDE
#include <vcg/space/ray3.h>
#include <vcg/space/box3.h>
#include <vcg/space/triangle3.h>
#ifndef VCG_INSIDE
#define VCG_INSIDE
#include <vcg/complex/algorithms/closest.h>
/// This static funtion is used to see if one point is inside a triangular mesh or not...
@ -58,14 +53,11 @@ namespace vcg {
template <class FaceSpatialIndexing,class TriMeshType>
class Inside
{
private:
public:
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 )
{
@ -74,22 +66,25 @@ namespace vcg {
typedef typename TriMeshType::CoordType CoordType;
const ScalarType EPSILON = 0.000001;
/// First test if the element is inside the bounding box of the mesh.
if( !( m.bbox.IsIn(test) ) ) return false;
if( !( m.bbox.IsIn(test) ) )
return false;
else
{
ScalarType dist;
CoordType Norm, ip, nearest;
FaceType *f = vcg::tri::GetClosestFace< TriMeshType, FaceSpatialIndexing >( m, _g_mesh, test, m.bbox.Diag(), dist, nearest, Norm, ip );
FaceType *f = vcg::tri::GetClosestFaceBase< TriMeshType, FaceSpatialIndexing >( m, _g_mesh, test, m.bbox.Diag(), dist, nearest, Norm, ip);
assert( f != NULL ); /// Check if there is any face in the mesh
/// If the point is on the face is considered inside.
if( ( test - nearest ).Norm() <= EPSILON ) return true;
if( ( test - nearest ).Norm() <= EPSILON )
return true;
/// Check if the closest point is inside a face
if( ( ip.V(0) > EPSILON ) && ( ip.V(1) > EPSILON ) && ( ip.V(2) > EPSILON ) )
{
/// Check if the test point is inside the mesh using the normal direction
vcg::Point3f debugn = f->N();
if( ( f->N() * ( test - nearest ) ) < 0 ) return true;
else return false;
if( ( f->N() * ( test - nearest ) ) < 0 )
return true;
else
return false;
}
/// In this case we are not sure because hit an edge or a vertex.
/// So we use a ray that go until the barycenter of found face, then see normal value again
@ -97,12 +92,16 @@ namespace vcg {
{
CoordType bary = vcg::Barycenter< FaceType >(*f);
/// Set ray : origin and direction
vcg::Ray3<ScalarType> r; r.Set( test, ( bary - test ) ); r.Normalize();
vcg::Ray3<ScalarType> r;
r.Set( test, ( bary - test ) );
r.Normalize();
FaceType *f1 = vcg::tri::DoRay< TriMeshType, FaceSpatialIndexing >( m, _g_mesh, r, m.bbox.Diag(), dist );
assert( f1 != NULL );
/// In this case normal direction is enough.
if( ( f1->N() * ( test - bary ) ) < 0 ) return true;
else return false;
if( ( f1->N() * ( test - bary ) ) < 0 )
return true;
else
return false;
}
}
@ -112,4 +111,4 @@ namespace vcg {
}
}
#endif
#endif // __VCG_TRIMESH_INSIDE

View File

@ -262,7 +262,7 @@ static void PerVertexNormalized(ComputeMeshType &m)
NormalizePerVertex(m);
}
/// \brief Equivalent to PerFace() and NormalizePerVertex()
/// \brief Equivalent to PerFace() and NormalizePerFace()
static void PerFaceNormalized(ComputeMeshType &m)
{
PerFace(m);

View File

@ -187,7 +187,7 @@ namespace vcg{
///contructor
RayIterator(Spatial_Idexing &_Si,
INTFUNCTOR _int_funct
INTFUNCTOR & _int_funct
,const ScalarType &_max_dist)
:Si(_Si),int_funct(_int_funct)
{