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); return (0);
} }
template <class MESH, class GRID> template <class MESH, class GRID>
typename MESH::FaceType * GetClosestFaceBase( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p, typename MESH::FaceType * GetClosestFaceBase( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
const typename GRID::ScalarType _maxDist,typename GRID::ScalarType & _minDist, const typename GRID::ScalarType _maxDist,typename GRID::ScalarType & _minDist,
typename GRID::CoordType &_closestPt) typename GRID::CoordType &_closestPt)
{ {
typedef typename GRID::ScalarType ScalarType; typedef typename GRID::ScalarType ScalarType;
typedef Point3<ScalarType> Point3x; typedef Point3<ScalarType> Point3x;
typedef FaceTmark<MESH> MarkerFace; typedef FaceTmark<MESH> MarkerFace;
MarkerFace mf; MarkerFace mf;
mf.SetMesh(&mesh); mf.SetMesh(&mesh);
vcg::face::PointDistanceBaseFunctor<ScalarType> PDistFunct; vcg::face::PointDistanceBaseFunctor<ScalarType> PDistFunct;
_minDist=_maxDist; _minDist=_maxDist;
return (gr.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt)); 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> template <class MESH, class GRID>
typename MESH::FaceType * GetClosestFaceEP( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p, 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/complex/algorithms/closest.h>
#include <vcg/space/ray3.h>
#include <vcg/space/box3.h>
#include <vcg/space/triangle3.h>
#ifndef VCG_INSIDE
#define VCG_INSIDE
/// This static funtion is used to see if one point is inside a triangular mesh or not... /// 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> template <class FaceSpatialIndexing,class TriMeshType>
class Inside class Inside
{ {
public:
private:
typedef typename FaceSpatialIndexing::CoordType CoordType; typedef typename FaceSpatialIndexing::CoordType CoordType;
typedef typename FaceSpatialIndexing::ScalarType ScalarType; typedef typename FaceSpatialIndexing::ScalarType ScalarType;
public:
/// Return true if the point is inside the mesh. /// Return true if the point is inside the mesh.
static bool Is_Inside( TriMeshType & m, FaceSpatialIndexing & _g_mesh, const CoordType & test ) static bool Is_Inside( TriMeshType & m, FaceSpatialIndexing & _g_mesh, const CoordType & test )
{ {
@ -74,22 +66,25 @@ namespace vcg {
typedef typename TriMeshType::CoordType CoordType; typedef typename TriMeshType::CoordType CoordType;
const ScalarType EPSILON = 0.000001; const ScalarType EPSILON = 0.000001;
/// First test if the element is inside the bounding box of the mesh. /// 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 else
{ {
ScalarType dist; ScalarType dist;
CoordType Norm, ip, nearest; 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 assert( f != NULL ); /// Check if there is any face in the mesh
/// If the point is on the face is considered inside. /// 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 /// Check if the closest point is inside a face
if( ( ip.V(0) > EPSILON ) && ( ip.V(1) > EPSILON ) && ( ip.V(2) > EPSILON ) ) 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 /// Check if the test point is inside the mesh using the normal direction
vcg::Point3f debugn = f->N(); if( ( f->N() * ( test - nearest ) ) < 0 )
if( ( f->N() * ( test - nearest ) ) < 0 ) return true; return true;
else return false; else
return false;
} }
/// In this case we are not sure because hit an edge or a vertex. /// 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 /// 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); CoordType bary = vcg::Barycenter< FaceType >(*f);
/// Set ray : origin and direction /// 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 ); FaceType *f1 = vcg::tri::DoRay< TriMeshType, FaceSpatialIndexing >( m, _g_mesh, r, m.bbox.Diag(), dist );
assert( f1 != NULL ); assert( f1 != NULL );
/// In this case normal direction is enough. /// In this case normal direction is enough.
if( ( f1->N() * ( test - bary ) ) < 0 ) return true; if( ( f1->N() * ( test - bary ) ) < 0 )
else return false; 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); NormalizePerVertex(m);
} }
/// \brief Equivalent to PerFace() and NormalizePerVertex() /// \brief Equivalent to PerFace() and NormalizePerFace()
static void PerFaceNormalized(ComputeMeshType &m) static void PerFaceNormalized(ComputeMeshType &m)
{ {
PerFace(m); PerFace(m);

View File

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