/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ /**************************************************************************** History $Log: not supported by cvs2svn $ Revision 1.7 2005/09/19 13:10:12 spinelli fixed bugs Revision 1.6 2005/09/14 14:34:41 spinelli used new version of Grid_ptr Revision 1.5 2005/05/30 09:42:05 spinelli std::std::vector sostituito con std::vector Revision 1.4 2005/05/30 09:13:08 ganovelli error in include Revision 1.3 2005/05/17 21:19:37 ganovelli some std::and typename missing (CRS4) Revision 1.2 2005/03/08 14:42:22 ganovelli added vcg header ****************************************************************************/ #ifndef __VCGLIB__UNIFY #define __VCGLIB__UNIFY #include #include #include #include namespace vcg { /** \addtogroup edgemesh */ /*@{*/ /** Class for computing unification of the vertices or of the edges */ template struct Unify{ template class Tmark { MESH_TYPE m; public: Tmark(MESH_TYPE &_m):m(_m){} void UnMarkAll(){m.UnMarkAll();} bool IsMarked(OBJ_TYPE* obj){return (m.IsMarked(obj->v));} void Mark(OBJ_TYPE* obj){m.Mark(obj->v);} }; typedef typename EdgeMeshType::VertexPointer VertexPointer; typedef typename EdgeMeshType::EdgePointer EdgePointer; typedef typename EdgeMeshType::ScalarType ScalarType; typedef typename EdgeMeshType::CoordType CoordType; struct PVertex:EdgeMeshType::VertexType { typedef typename EdgeMeshType::ScalarType ScalarType; VertexPointer v; // the two Vertex pointer are ordered! EdgePointer e; // the edge where this vertex belong int z; // index in [0..2] of the edge of the face PVertex(EdgePointer pe, const int nz ):e(pe),z(nz),v(pe->V(nz)){} /*bool Dist(Point3 p,ScalarType & d,Point3& res) { res = p; ScalarType _d =vcg::Distance(p,v->P()); if(d > _d) { d = _d; return true; } return false; }*/ void GetBBox(vcg::Box3 & bb){ bb.Add(v->P()); } bool IsD(){ return v->IsD(); } }; typedef typename GridStaticPtr< PVertex > GridType; static void Join(PVertex pv0,PVertex & pv1){ pv1.e->V(pv1.z) = pv0.v; pv1.e = NULL; } class BackCompDist { public: inline bool operator () (const PVertex & obj, const CoordType & pt, ScalarType & mindist, CoordType & result) { result = pt; ScalarType _d =vcg::Distance(result,obj.v->P()); if(mindist < _d) { mindist = _d; return true; } return false; } }; static GridType & Grid(){static GridType grid; return grid; } static void Vertices(EdgeMeshType & em, ScalarType epsilon){ typename EdgeMeshType::EdgeIterator ei; typedef Tmark Marker; Marker tm=Marker(em); bool lastRound ; if(em.vn){ vcg::edge::UpdateBounding::Box(em); //Grid().SetBBox(em.bbox); std::vector pv; for(ei = em.edges.begin(); ei != em.edges.end();++ei){ pv.push_back(PVertex(&*ei,0)); pv.push_back(PVertex(&*ei,1)); } Grid().Set(pv.begin(), pv.end() ); typename std::vector::iterator pvi; Point3 p; PVertex * closest; do{ lastRound = true; for(pvi = pv.begin(); pvi != pv.end(); ++pvi) if((*pvi).e) { float eps = epsilon; Point3 vpos =(*pvi).v->P() ; (*pvi).v->SetD(); ScalarType max_dist=em.bbox.Diag(); ScalarType min_dist = 0; p = (vcg::trimesh::GetClosestVertex( em, Grid(), vpos, max_dist, min_dist))->P(); //closest = Grid().GetClosest(vpos, max_dist, BackCompDist(), eps, p,tm); //closest = Grid().GetClosest(vpos,eps,p); (*pvi).v->ClearD(); if(closest){ if(closest->e) { Join(*pvi,*closest); lastRound = false; } } } }while(!lastRound); } } // end Vertices }; // end class } // end namespace #endif