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 #ifndef __VCGLIB__UNIFY
00052 #define __VCGLIB__UNIFY
00053
00054 #include <vcg/space/index/grid_static_ptr.h>
00055 #include <vcg/space/box3.h>
00056 #include <vcg/complex/edgemesh/update/bounding.h>
00057 #include <vector>
00058
00059 namespace vcg
00060 {
00066 template <class EdgeMeshType>
00067 struct Unify{
00068
00069 template <class MESH_TYPE,class OBJ_TYPE>
00070 class Tmark
00071 {
00072 MESH_TYPE m;
00073 public:
00074 Tmark(MESH_TYPE &_m):m(_m){}
00075 void UnMarkAll(){m.UnMarkAll();}
00076 bool IsMarked(OBJ_TYPE* obj){return (m.IsMarked(obj->v));}
00077 void Mark(OBJ_TYPE* obj){m.Mark(obj->v);}
00078 };
00079
00080
00081 typedef typename EdgeMeshType::VertexPointer VertexPointer;
00082 typedef typename EdgeMeshType::EdgePointer EdgePointer;
00083 typedef typename EdgeMeshType::ScalarType ScalarType;
00084 typedef typename EdgeMeshType::CoordType CoordType;
00085
00086 struct PVertex:EdgeMeshType::VertexType
00087 {
00088 typedef typename EdgeMeshType::ScalarType ScalarType;
00089 VertexPointer v;
00090 EdgePointer e;
00091 int z;
00092 PVertex(EdgePointer pe, const int nz ):e(pe),z(nz),v(pe->V(nz)){}
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void GetBBox(vcg::Box3<ScalarType> & bb){
00106 bb.Add(v->P());
00107 }
00108 bool IsD(){
00109 return v->IsD();
00110 }
00111 };
00112 typedef GridStaticPtr< PVertex > GridType;
00113
00114 static void Join(PVertex pv0,PVertex & pv1){
00115 pv1.e->V(pv1.z) = pv0.v;
00116 pv1.e = NULL;
00117 }
00118
00119 class BackCompDist {
00120 public:
00121 inline bool operator () (const PVertex & obj, const CoordType & pt, ScalarType & mindist, CoordType & result) {
00122 result = pt;
00123 ScalarType _d =vcg::Distance(result,obj.v->P());
00124 if(mindist < _d)
00125 {
00126 mindist = _d;
00127 return true;
00128 }
00129 return false;
00130 }
00131 };
00132
00133 static GridType & Grid(){static GridType grid; return grid; }
00134
00135 static void Vertices(EdgeMeshType & em, ScalarType epsilon){
00136 typename EdgeMeshType::EdgeIterator ei;
00137
00138 typedef Tmark<EdgeMeshType,PVertex> Marker;
00139 Marker tm=Marker(em);
00140
00141 bool lastRound ;
00142 if(em.vn){
00143 vcg::edg::UpdateBounding<EdgeMeshType>::Box(em);
00144
00145
00146 std::vector<PVertex> pv;
00147 for(ei = em.edges.begin(); ei != em.edges.end();++ei){
00148 pv.push_back(PVertex(&*ei,0));
00149 pv.push_back(PVertex(&*ei,1));
00150 }
00151 Grid().Set(pv.begin(), pv.end() );
00152 typename std::vector<PVertex>::iterator pvi;
00153 Point3<ScalarType> p;
00154 PVertex * closest;
00155 do{
00156 lastRound = true;
00157 for(pvi = pv.begin(); pvi != pv.end(); ++pvi)
00158 if((*pvi).e)
00159 {
00160 float eps = epsilon;
00161 Point3<ScalarType> vpos =(*pvi).v->P() ;
00162 (*pvi).v->SetD();
00163 ScalarType max_dist=em.bbox.Diag();
00164 ScalarType min_dist = 0;
00165 p = (vcg::tri::GetClosestVertex<EdgeMeshType, GridType>( em, Grid(), vpos,
00166 max_dist, min_dist))->P();
00167
00168
00169
00170 (*pvi).v->ClearD();
00171
00172
00173 if(closest){
00174
00175 if(closest->e)
00176 {
00177 Join(*pvi,*closest);
00178 lastRound = false;
00179 }
00180 }
00181
00182 }
00183 }while(!lastRound);
00184
00185 }
00186 }
00187 };
00188
00189 }
00190
00191 #endif