From f480f01a3f553cc47412e26e5a1089dffbce4c53 Mon Sep 17 00:00:00 2001 From: ganovelli Date: Fri, 1 Oct 2004 18:54:22 +0000 Subject: [PATCH] first working release --- vcg/complex/edgemesh/unify.h | 104 +++++++++++++++++++++++++++++++ vcg/complex/intersection.h | 115 +++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 vcg/complex/edgemesh/unify.h create mode 100644 vcg/complex/intersection.h diff --git a/vcg/complex/edgemesh/unify.h b/vcg/complex/edgemesh/unify.h new file mode 100644 index 00000000..5ce1da30 --- /dev/null +++ b/vcg/complex/edgemesh/unify.h @@ -0,0 +1,104 @@ + +#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{ + typedef typename EdgeMeshType::VertexPointer VertexPointer; + typedef typename EdgeMeshType::EdgePointer EdgePointer; + typedef typename EdgeMeshType::ScalarType ScalarType; + + struct PVertex + { + 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< std::vector > GridType; + + static void Join(PVertex pv0,PVertex & pv1){ + pv1.e->V(pv1.z) = pv0.v; + pv1.e = NULL; + } + + static GridType & Grid(){static GridType grid; return grid; } + + static void Vertices(EdgeMeshType & em, ScalarType epsilon){ + EdgeMeshType::EdgeIterator ei; + bool lastRound ; + if(em.vn){ + vcg::edge::UpdateBounding::Box(em); + Grid().SetBBox(em.bbox); + + 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); + 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(); + 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 \ No newline at end of file diff --git a/vcg/complex/intersection.h b/vcg/complex/intersection.h new file mode 100644 index 00000000..560d8a29 --- /dev/null +++ b/vcg/complex/intersection.h @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include + + + +namespace vcg{ + +/** \addtogroup complex */ +/*@{*/ +/** + Function computing the intersection between a grid and a plane. It returns all the cells intersected +*/ +template < typename GridType,typename ScalarType> +bool Intersect( GridType & grid,Plane3 plane, vector &cells){ + Point3d p,_d; + Plane3d pl; + _d.Import(plane.Direction()); + pl.SetDirection(_d); + pl.SetOffset(plane.Offset()); + for( int ax = 0; ax <3; ++ax) + { int axis = ax; + int axis0 = (axis+1)%3; + int axis1 = (axis+2)%3; + int i,j; + Point3i pi; + + Segment3 seg; + seg.P0().Import(grid.bbox.min); + seg.P1().Import(grid.bbox.min); + seg.P1()[axis] = grid.bbox.max[axis]; + + for(i = 0 ; i <= grid.siz[axis0]; ++i){ + for(j = 0 ; j <= grid.siz[axis1]; ++j) + { + seg.P0()[axis0] = grid.bbox.min[axis0]+ (i+0.1) * grid.voxel[axis0] ; + seg.P1()[axis0] = grid.bbox.min[axis0]+ (i+0.1) * grid.voxel[axis0]; + seg.P0()[axis1] = grid.bbox.min[axis1]+ (j+0.1) * grid.voxel[axis1]; + seg.P1()[axis1] = grid.bbox.min[axis1]+ (j+0.1) * grid.voxel[axis1]; + if ( Intersection(pl,seg,p)) + { + pi[axis] = min(max(0,floor((p[axis ]-grid.bbox.min[axis])/grid.voxel[axis])),grid.siz[axis]); + pi[axis0] = i; + pi[axis1] = j; + grid.Grid(pi,axis,cells); + } + } + } + } + sort(cells.begin(),cells.end()); + cells.erase(unique(cells.begin(),cells.end()),cells.end()); + + return false; + } + +/*@}*/ + +/** \addtogroup complex */ +/*@{*/ +/** + Function computing the intersection between a trimesh and a plane. It returns an EdgeMesh. + Note: This version always returns a segment for each triangle of the mesh which intersects with the plane. In other + words there are 2*n vertices where n is the number of segments fo the mesh. You can run vcg::edge::Unify to unify + the vertices closer that a given value epsilon. Note that, due to subtraction error during triangle plane intersection, + it is not safe to put epsilon to 0. +*/ +// TODO si dovrebbe considerare la topologia face-face della trimesh per derivare quella della edge mesh.. +template < typename TriMeshType, typename EdgeMeshType, class ScalarType> +bool Intersection( TriMeshType & m, Plane3 pl,EdgeMeshType & em,double& ave_length, + typename GridStaticPtr *grid, + typename vector< typename GridStaticPtr::Cell* >& cells){ + typedef typename TriMeshType::FaceContainer FaceContainer; + typedef GridStaticPtr GridType; + EdgeMeshType::VertexIterator vi; + TriMeshType::FaceIterator fi; + + Intersect(*grid,pl,cells); + Segment3 seg; + ave_length = 0.0; + vector::iterator ic; + GridType::Cell fs,ls; + for(ic = cells.begin(); ic != cells.end();++ic) + { + grid->Grid(*ic,fs,ls); + GridType::Link * lk = fs; + while(lk != ls){ + TriMeshType::FaceType & face = *(lk->Elem()); + if(!face.IsS()) + { + face.SetS(); + if(vcg::Intersection(pl,face,seg))// intersezione piano triangolo + { + // add to em + ave_length+=seg.Length(); + vcg::edge::Allocator::AddEdges(em,1); + vi = vcg::edge::Allocator::AddVertices(em,2); + (*vi).P() = seg.P0(); + em.edges.back().V(0) = &(*vi); + vi++; + (*vi).P() = seg.P1(); + em.edges.back().V(1) = &(*vi); + } + }//endif + lk++; + }//end while + } + ave_length/=em.en; + + return true; + } +/*@}*/ +} // end namespace vcg \ No newline at end of file