00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 #ifndef __VCG_TRIMESH_CLOSEST
00127 #define __VCG_TRIMESH_CLOSEST
00128 #include <math.h>
00129
00130 #include <vcg/space/point3.h>
00131 #include <vcg/space/box3.h>
00132 #include <vcg/space/point4.h>
00133 #include <vcg/math/base.h>
00134 #include <vcg/simplex/face/distance.h>
00135 #include <vcg/simplex/vertex/distance.h>
00136 #include <vcg/space/intersection3.h>
00137 #include <vcg/space/index/space_iterators.h>
00138 #include <vcg/complex/trimesh/base.h>
00139
00140 namespace vcg {
00141 namespace tri {
00142
00143
00144 template <class MESH_TYPE,class OBJ_TYPE>
00145 class Tmark
00146 {
00147 MESH_TYPE *m;
00148 public:
00149 Tmark(){}
00150 Tmark( MESH_TYPE *m) {SetMesh(m);}
00151 void UnMarkAll(){ vcg::tri::UnMarkAll(*m);}
00152 bool IsMarked(OBJ_TYPE* obj){return (vcg::tri::IsMarked(*m,obj));}
00153 void Mark(OBJ_TYPE* obj){ vcg::tri::Mark(*m,obj);}
00154 void SetMesh(MESH_TYPE *_m)
00155 {m=_m;}
00156 };
00157
00158 template <class MESH_TYPE>
00159 class FaceTmark:public Tmark<MESH_TYPE,typename MESH_TYPE::FaceType>
00160 {
00161 public:
00162 FaceTmark() {}
00163 FaceTmark(MESH_TYPE *m) {this->SetMesh(m);}
00164 };
00165
00166 template <class MESH_TYPE>
00167 class VertTmark
00168 {
00169 public:
00170 typedef typename MESH_TYPE::VertexType VertexType;
00171 inline VertTmark(){}
00172 inline VertTmark(MESH_TYPE *){}
00173 inline void UnMarkAll() const {}
00174 inline bool IsMarked(VertexType*) const { return false; }
00175 inline void Mark(VertexType*) const {}
00176 inline void SetMesh(void * ) const {}
00177 };
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 template <class MESH, class GRID>
00195 typename MESH::FaceType * GetClosestFace( MESH & mesh, GRID & gr, const typename GRID::CoordType & _p,
00196 const typename GRID::ScalarType & _maxDist, typename GRID::ScalarType & _minDist,
00197 typename GRID::CoordType &_closestPt, typename GRID::CoordType & _normf,
00198 typename GRID::CoordType & _ip)
00199 {
00200 typedef typename GRID::ScalarType ScalarType;
00201 typedef Point3<ScalarType> Point3x;
00202
00203 typedef FaceTmark<MESH> MarkerFace;
00204 MarkerFace mf(&mesh);
00205 vcg::face::PointDistanceFunctor<ScalarType> FDistFunct;
00206 _minDist=_maxDist;
00207 typename MESH::FaceType* bestf= gr.GetClosest(FDistFunct, mf, _p, _maxDist, _minDist, _closestPt);
00208
00209 if(_maxDist> ScalarType(fabs(_minDist)))
00210 {
00211
00212 typename MESH::ScalarType alfa, beta, gamma;
00213
00214 InterpolationParameters<typename MESH::FaceType,typename MESH::ScalarType>(*bestf,bestf->N(),_closestPt, alfa, beta, gamma);
00215 _normf = (bestf->V(0)->cN())*alfa+
00216 (bestf->V(1)->cN())*beta+
00217 (bestf->V(2)->cN())*gamma ;
00218 _ip=Point3x(alfa,beta,gamma);
00219
00220
00221 _minDist = fabs(_minDist);
00222 return(bestf);
00223 }
00224 return (0);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 template <class MESH, class GRID>
00241 typename MESH::FaceType * GetClosestFace( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
00242 const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist,
00243 typename GRID::CoordType &_closestPt)
00244 {
00245 typedef typename GRID::ScalarType ScalarType;
00246 typedef Point3<ScalarType> Point3x;
00247 typedef FaceTmark<MESH> MarkerFace;
00248 MarkerFace mf;
00249 mf.SetMesh(&mesh);
00250 vcg::face::PointDistanceFunctor<ScalarType> PDistFunct;
00251 _minDist=_maxDist;
00252 return (gr.GetClosest(PDistFunct,mf,_p,_maxDist,_minDist,_closestPt));
00253 }
00254
00255 template <class MESH, class GRID>
00256 typename MESH::FaceType * GetClosestFaceNormal(MESH & mesh,GRID & gr,const typename MESH::VertexType & _p,
00257 const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist,
00258 typename GRID::CoordType &_closestPt)
00259 {
00260 typedef typename GRID::ScalarType ScalarType;
00261 typedef FaceTmark<MESH> MarkerFace;
00262 MarkerFace mf;
00263 mf.SetMesh(&mesh);
00264 typedef vcg::face::PointNormalDistanceFunctor<typename MESH::VertexType> PDistFunct;
00265 PDistFunct fn;
00266 _minDist=_maxDist;
00267
00268 return (gr.template GetClosest <PDistFunct,MarkerFace>(fn,mf,_p,_maxDist,_minDist,_closestPt));
00269 }
00270
00271 template <class MESH, class GRID>
00272 typename MESH::VertexType * GetClosestVertex( MESH & mesh,GRID & gr,const typename GRID::CoordType & _p,
00273 const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist )
00274 {
00275 typedef typename GRID::ScalarType ScalarType;
00276 typedef Point3<ScalarType> Point3x;
00277 typedef VertTmark<MESH> MarkerVert;
00278 MarkerVert mv;
00279 mv.SetMesh(&mesh);
00280 typedef vcg::vertex::PointDistanceFunctor<typename MESH::ScalarType> VDistFunct;
00281 VDistFunct fn;
00282 _minDist=_maxDist;
00283 Point3x _closestPt;
00284 return (gr.template GetClosest<VDistFunct,MarkerVert>(fn,mv,_p,_maxDist,_minDist,_closestPt));
00285 }
00286
00287 template <class MESH, class GRID>
00288 typename MESH::VertexType * GetClosestVertexNormal( MESH & mesh,GRID & gr,const typename MESH::VertexType & _p,
00289 const typename GRID::ScalarType & _maxDist,typename GRID::ScalarType & _minDist )
00290 {
00291 typedef typename GRID::ScalarType ScalarType;
00292 typedef Point3<ScalarType> Point3x;
00293 typedef VertTmark<MESH> MarkerVert;
00294 MarkerVert mv;
00295 mv.SetMesh(&mesh);
00296 typedef vcg::vertex::PointNormalDistanceFunctor<typename MESH::VertexType> VDistFunct;
00297 VDistFunct fn;
00298 _minDist=_maxDist;
00299 Point3x _closestPt;
00300 return (gr.template GetClosest <VDistFunct,MarkerVert>(fn,mv,_p,_maxDist,_minDist,_closestPt));
00301 }
00302
00303 template <class MESH, class GRID, class OBJPTRCONTAINER,class DISTCONTAINER, class POINTCONTAINER>
00304 unsigned int GetKClosestFace(MESH & mesh,GRID & gr, const unsigned int _k,
00305 const typename GRID::CoordType & _p, const typename GRID::ScalarType & _maxDist,
00306 OBJPTRCONTAINER & _objectPtrs,DISTCONTAINER & _distances, POINTCONTAINER & _points)
00307 {
00308 typedef FaceTmark<MESH> MarkerFace;
00309 MarkerFace mf;
00310 mf.SetMesh(&mesh);
00311 vcg::face::PointDistanceFunctor<typename MESH::ScalarType> FDistFunct;
00312 return (gr.GetKClosest
00313 (FDistFunct,mf,_k,_p,_maxDist,_objectPtrs,_distances,_points));
00314 }
00315
00316
00317
00318 template <class MESH, class GRID, class OBJPTRCONTAINER,class DISTCONTAINER, class POINTCONTAINER>
00319 unsigned int GetKClosestFaceBase(MESH & mesh,GRID & gr, const unsigned int _k,
00320 const typename GRID::CoordType & _p, const typename GRID::ScalarType & _maxDist,
00321 OBJPTRCONTAINER & _objectPtrs,DISTCONTAINER & _distances, POINTCONTAINER & _points)
00322 {
00323 typedef FaceTmark<MESH> MarkerFace;
00324 MarkerFace mf;
00325 mf.SetMesh(&mesh);
00326 vcg::face::PointDistanceBaseFunctor<typename MESH::ScalarType> FDistFunct;
00327 return (gr.GetKClosest
00328 (FDistFunct,mf,_k,_p,_maxDist,_objectPtrs,_distances,_points));
00329 }
00330
00331 template <class MESH, class GRID, class OBJPTRCONTAINER,class DISTCONTAINER, class POINTCONTAINER>
00332 unsigned int GetKClosestVertex(MESH & mesh,GRID & gr, const unsigned int _k,
00333 const typename GRID::CoordType & _p, const typename GRID::ScalarType & _maxDist,
00334 OBJPTRCONTAINER & _objectPtrs,DISTCONTAINER & _distances, POINTCONTAINER & _points)
00335 {
00336 typedef VertTmark<MESH> MarkerVert;
00337 MarkerVert mv;
00338 mv.SetMesh(&mesh);
00339 typedef vcg::vertex::PointDistanceFunctor<typename MESH::ScalarType> VDistFunct;
00340 VDistFunct distFunct;
00341 return (gr.GetKClosest
00342 (distFunct,mv,_k,_p,_maxDist,_objectPtrs,_distances,_points));
00343 }
00344
00345 template <class MESH, class GRID, class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
00346 unsigned int GetInSphereFace(MESH & mesh,
00347 GRID & gr,
00348 const typename GRID::CoordType & _p,
00349 const typename GRID::ScalarType & _r,
00350 OBJPTRCONTAINER & _objectPtrs,
00351 DISTCONTAINER & _distances,
00352 POINTCONTAINER & _points)
00353 {
00354 typedef FaceTmark<MESH> MarkerFace;
00355 MarkerFace mf;
00356 mf.SetMesh(&mesh);
00357 typedef vcg::face::PointDistanceFunctor<typename MESH::ScalarType> FDistFunct;
00358 return (gr.GetInSphere
00359 (FDistFunct(),mf,_p,_r,_objectPtrs,_distances,_points));
00360 }
00361
00362 template <class MESH, class GRID, class OBJPTRCONTAINER, class DISTCONTAINER, class POINTCONTAINER>
00363 unsigned int GetInSphereVertex(MESH & mesh,
00364 GRID & gr,
00365 const typename GRID::CoordType & _p,
00366 const typename GRID::ScalarType & _r,
00367 OBJPTRCONTAINER & _objectPtrs,
00368 DISTCONTAINER & _distances,
00369 POINTCONTAINER & _points)
00370 {
00371 typedef VertTmark<MESH> MarkerVert;
00372 MarkerVert mv;
00373 mv.SetMesh(&mesh);
00374 typedef vcg::vertex::PointDistanceFunctor<typename MESH::ScalarType> VDistFunct;
00375 VDistFunct fn;
00376 return (gr.GetInSphere
00377 (fn, mv,_p,_r,_objectPtrs,_distances,_points));
00378 }
00379
00380 template <class MESH, class GRID, class OBJPTRCONTAINER>
00381 unsigned int GetInBoxFace(MESH & mesh,
00382 GRID & gr,
00383 const vcg::Box3<typename GRID::ScalarType> _bbox,
00384 OBJPTRCONTAINER & _objectPtrs)
00385 {
00386 typedef FaceTmark<MESH> MarkerFace;
00387 MarkerFace mf;
00388 mf.SetMesh(&mesh);
00389 return(gr.GetInBox(mf,_bbox,_objectPtrs));
00390 }
00391
00392 template <class MESH, class GRID, class OBJPTRCONTAINER>
00393 unsigned int GetInBoxVertex(MESH & mesh,
00394 GRID & gr,
00395 const vcg::Box3<typename GRID::ScalarType> _bbox,
00396 OBJPTRCONTAINER & _objectPtrs)
00397 {
00398 typedef VertTmark<MESH> MarkerVert;
00399 MarkerVert mv;
00400 mv.SetMesh(&mesh);
00401 return(gr.GetInBox(mv,_bbox,_objectPtrs));
00402 }
00403
00404 template <class MESH, class GRID>
00405 typename GRID::ObjPtr DoRay(MESH & mesh,GRID & gr, const Ray3<typename GRID::ScalarType> & _ray,
00406 const typename GRID::ScalarType & _maxDist, typename GRID::ScalarType & _t)
00407 {
00408 typedef typename MESH::FaceType FaceType;
00409 typedef typename MESH::ScalarType ScalarType;
00410 typedef FaceTmark<MESH> MarkerFace;
00411 MarkerFace mf;
00412 mf.SetMesh(&mesh);
00413 Ray3<typename GRID::ScalarType> _ray1=_ray;
00414 _ray1.Normalize();
00415 typedef vcg::RayTriangleIntersectionFunctor<true> FintFunct;
00416 FintFunct ff;
00417 return(gr.DoRay(ff,mf,_ray1,_maxDist,_t));
00418 }
00419
00420 template <class MESH, class GRID>
00421 typename GRID::ObjPtr DoRay(MESH & mesh,GRID & gr, const Ray3<typename GRID::ScalarType> & _ray,
00422 const typename GRID::ScalarType & _maxDist,
00423 typename GRID::ScalarType & _t,
00424 typename GRID::CoordType & _normf)
00425 {
00426 typedef typename MESH::FaceType FaceType;
00427 typedef typename MESH::ScalarType ScalarType;
00428 typedef FaceTmark<MESH> MarkerFace;
00429 MarkerFace mf;
00430 mf.SetMesh(&mesh);
00431 typedef vcg::RayTriangleIntersectionFunctor<true> FintFunct;
00432 FintFunct fintfunct;
00433 Ray3<typename GRID::ScalarType> _ray1=_ray;
00434 _ray1.Normalize();
00435 FaceType *f=gr.DoRay(fintfunct,mf,_ray1,_maxDist,_t);
00436 typename GRID::CoordType dir=_ray.Direction();
00437 dir.Normalize();
00438 typename GRID::CoordType int_point=_ray.Origin()+_ray1.Direction()*_t;
00439 typename GRID::ScalarType alfa,beta,gamma;
00440 if (f!=NULL)
00441 {
00442 InterpolationParameters<FaceType,ScalarType>(*f,f->N(),int_point, alfa, beta, gamma);
00443 _normf = (f->V(0)->cN())*alfa+
00444 (f->V(1)->cN())*beta+
00445 (f->V(2)->cN())*gamma ;
00446 }
00447 return f;
00448 }
00449
00452 template <class MESH, class GRID, class OBJPTRCONTAINER, class COORDCONTAINER>
00453 void RaySpherical(MESH & mesh,GRID & gr, const Ray3<typename GRID::ScalarType> & _ray,
00454 const typename GRID::ScalarType & _maxDist,
00455 const typename GRID::ScalarType & _theta_interval,
00456 const typename GRID::ScalarType & _phi_interval,
00457 const int &n_samples,
00458 OBJPTRCONTAINER & _objectPtrs,
00459 COORDCONTAINER & _pos,
00460 COORDCONTAINER & _norm)
00461 {
00462 typedef typename MESH::FaceType FaceType;
00463 typedef typename MESH::ScalarType ScalarType;
00464 ScalarType delta_theta=_theta_interval/(ScalarType)(n_samples*2);
00465 ScalarType delta_phi =_phi_interval/(ScalarType)(n_samples*2);
00466 ScalarType theta_init,phi_init,ro;
00467 typename GRID::CoordType dir0=_ray.Direction();
00468 dir0.ToPolarRad(ro,theta_init,phi_init);
00469 for (int x=-n_samples;x<=n_samples;x++)
00470 for (int y=-n_samples;y<=n_samples;y++)
00471 {
00472 ScalarType theta=theta_init+x*delta_theta;
00473 if (theta<0) theta=2.0*M_PI-theta;
00474 ScalarType phi=phi_init+y*delta_phi;
00475
00476 typename GRID::CoordType dir;
00477 dir.FromxPolar(ro,theta,phi);
00478 dir.Normalize();
00479 Ray3<typename GRID::ScalarType> curr_ray(_ray.Origin(),dir);
00480 typename GRID::ScalarType _t;
00481 typename GRID::ObjPtr f=NULL;
00482 f=DoRay(mesh,gr,curr_ray,_maxDist,_t);
00483 if (f!=NULL)
00484 {
00485 typename GRID::CoordType pos=curr_ray.Origin()+curr_ray.Direction()*_t;
00486 _objectPtrs.push_back(f);
00487 _pos.push_back(pos);
00488
00490 typename GRID::ScalarType alfa,beta,gamma;
00491 InterpolationParameters<FaceType,ScalarType>(*f,*f.N(),pos, alfa, beta, gamma);
00492 typename GRID::CoordType norm = (f->V(0)->cN())*alfa+
00493 (f->V(1)->cN())*beta+
00494 (f->V(2)->cN())*gamma ;
00495 _norm.push_back(norm);
00496 }
00497 }
00498 }
00499
00500
00501
00502 template <class GRID,class MESH>
00503 class ClosestFaceIterator:public vcg::ClosestIterator<GRID,
00504 vcg::face::PointDistanceFunctor<typename MESH::ScalarType>, FaceTmark<MESH> >
00505 {
00506 public:
00507 typedef GRID GridType;
00508 typedef MESH MeshType;
00509 typedef FaceTmark<MESH> MarkerFace;
00510 typedef vcg::face::PointDistanceFunctor<typename MESH::ScalarType> PDistFunct;
00511 typedef vcg::ClosestIterator<GRID,PDistFunct, FaceTmark<MESH> > ClosestBaseType;
00512 typedef typename MESH::FaceType FaceType;
00513 typedef typename MESH::ScalarType ScalarType;
00514
00515
00516 ClosestFaceIterator(GridType &_Si):ClosestBaseType(_Si,PDistFunct()){}
00517
00518
00519 void SetMesh(MeshType *m)
00520 {this->tm.SetMesh(m);}
00521 };
00522
00523 template <class GRID,class MESH>
00524 class ClosestVertexIterator:public vcg::ClosestIterator<GRID, vcg::vertex::PointDistanceFunctor<typename MESH::ScalarType>, VertTmark<MESH> >
00525 {
00526 public:
00527 typedef GRID GridType;
00528 typedef MESH MeshType;
00529 typedef VertTmark<MESH> MarkerVert;
00530 typedef vcg::vertex::PointDistanceFunctor<typename MESH::ScalarType> VDistFunct;
00531 typedef vcg::ClosestIterator<GRID, VDistFunct, VertTmark<MESH> > ClosestBaseType;
00532 VDistFunct fn;
00533 ClosestVertexIterator(GridType &_Si):ClosestBaseType(_Si,fn){}
00534
00535
00536 void SetMesh(MeshType *m)
00537 {this->tm.SetMesh(m);}
00538 };
00539
00540 template <class GRID,class MESH>
00541 class TriRayIterator:public vcg::RayIterator<GRID,vcg::RayTriangleIntersectionFunctor<true>,FaceTmark<MESH> >
00542 {
00543 public:
00544 typedef GRID GridType;
00545 typedef MESH MeshType;
00546 typedef FaceTmark<MESH> MarkerFace;
00547 typedef vcg::RayTriangleIntersectionFunctor<true> FintFunct;
00548 typedef vcg::RayIterator<GRID,FintFunct, FaceTmark<MESH> > RayBaseType;
00549 typedef typename MESH::FaceType FaceType;
00550 typedef typename MESH::ScalarType ScalarType;
00551
00552 TriRayIterator(GridType &_Si,const ScalarType &max_d):RayBaseType(_Si,FintFunct(),max_d){}
00553
00554
00555 void SetMesh(MeshType *m)
00556 {this->tm.SetMesh(m);}
00557
00558 };
00559
00560 }
00561 }
00562
00563 #endif