/**************************************************************************** * 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.4 2004/06/01 17:12:46 ganovelli addVertices corrected (two copies instead of specializing te call) and put static (also addTetra) * g++ compliant * Revision 1.3 2004/05/31 16:01:56 pietroni added function addtetra Revision 1.2 2004/05/14 15:14:34 turini Added $Log: not supported by cvs2svn $ Added Revision 1.4 2004/06/01 17:12:46 ganovelli Added addVertices corrected (two copies instead of specializing te call) Added and put static (also addTetra) * g++ compliant * Added Added Revision 1.3 2004/05/31 16:01:56 pietroni Added added function addtetra Added for CVS History Log Revision 1.1 2004/19/04 13:05 pietroni Initial commit ****************************************************************************/ #ifndef __VCG_TETRA_ALLOCATE #define __VCG_TETRA_ALLOCATE #include <vector> using namespace std; namespace vcg { namespace tetra { /** \addtogroup tetramesh */ /*@{*/ /** Class Allocate. This is class for Allocate new vertices or tetrahedron on the mesh. @param TM_TYPE (Template Parameter) Specifies the type of the tetrahedral mesh. */ template < class TM_TYPE > class Allocator { public: /// The tetramesh type typedef TM_TYPE TetraMeshType; /// The vertex type typedef typename TM_TYPE::VertexType VertexType; /// The tetrahedron type typedef typename TM_TYPE::TetraType TetraType; /// The type of vertex iterator typedef typename TM_TYPE::VertexIterator VertexIterator; /// The type of tetra iterator typedef typename TM_TYPE::TetraIterator TetraIterator; /// The type of constant vertex iterator typedef typename TM_TYPE::const_VertexIterator const_VertexIterator; /// The type of constant face iterator typedef typename TM_TYPE::const_TetraIterator const_TetraIterator; public: /** Function to add n vertices to the mesh. The second parameter hold a vector of pointers to pointer to elements of the mesh that should be updated after a possible vector realloc. @param n Il numero di vertici che si vuole aggiungere alla mesh. @param local_var Vettore di variabili locali che rappresentano puntatori a vertici. restituisce l'iteratore al primo elemento aggiunto. */ static VertexIterator AddVertices(TetraMeshType &m,int n, vector<VertexType **> &local_var) { VertexIterator oldbegin, newbegin; oldbegin = m.vert.begin(); VertexIterator last=m.vert.end(); if(m.vert.empty()) last=(VertexIterator)0; // if the vector is empty we cannot find the last valid element else --last; unsigned int siz=0; #ifdef __STL_CONFIG_H if(last!=(VertexIterator)0) distance(m.vert.begin(),last,siz); #else if(last!=(VertexIterator)0) siz=distance(m.vert.begin(),last); #endif for(unsigned int i=0; i<n; ++i) { m.vert.push_back(VertexType()); m.vert.back().ClearFlags(); } m.vn+=n; newbegin = m.vert.begin(); if(newbegin != oldbegin) { TetraIterator f; for (f=m.tetra.begin(); f!=m.tetra.end(); ++f) if(!(*f).IsD()) for(unsigned int k=0; k<4; ++k) (*f).V(k)= (*f).V(k)-&*oldbegin+&*newbegin; for(unsigned int j=0; j<local_var.size(); ++j) if((*local_var[j]) !=0 ) *local_var[j] = *local_var[j]-&*oldbegin+&*newbegin; // deve restituire l'iteratore alla prima faccia aggiunta; // e poiche' lo spazio e' cambiato si ricalcola last da zero if(last!=(VertexIterator)0) { last = m.vert.begin(); advance(last,siz+1); } else last=m.vert.begin(); } else { // se non e'cambiato lo spazio (vector abbastanza grande o lista) if(last==(VertexIterator)0) last = m.vert.begin(); // se il vettore era vuoto si restituisce begin else advance(last,1); // altrimenti il primo dopo quello che era in precedenza l'ultimo valido. } return last; } /** Function to add n vertices to the mesh. @param n Il numero di vertici che si vuole aggiungere alla mesh. */ static VertexIterator AddVertices(TetraMeshType &m,int n) { vector<VertexType **> empty_var; return AddVertices(m,n,empty_var); } struct InsertedVT{ InsertedVT(VertexType *_v, TetraType *_t, int _z):v(_v),t(_t),z(_z){} VertexType *v; TetraType *t; int z; const bool operator <(const InsertedVT & o){ return (v<o.v); } const bool operator ==(const InsertedVT & o){ return (v==o.v); } const bool operator !=(const InsertedVT & o){ return (v!=o.v); } }; /** Function to add n tetrafedron to the mesh. @param n number of vertices we want to add. */ static TetraIterator AddTetra(TetraMeshType &m,int n) { unsigned int sz = m.tetra.size(); m.tetra.resize(sz+n); TetraIterator ti =m.tetra.begin(); advance(ti,sz); m.tn+=n; return ti; } /** Crate a copy of the mesh with tetrahedron that are into the templated container @param ST_CONT (Template Parameter) Specifies the type of the container of tetrahedron. @param subSet Container of tetrahedron. @param m destination mesh. */ template <class STL_CONT > static void SubSetT(STL_CONT & subSet, TetraMeshType & m) { vector< InsertedVT > newVertices; typename STL_CONT :: iterator pfi; newVertices.clear(); for(pfi = subSet.begin(); pfi != subSet.end(); ++pfi) m.tetra.push_back((*pfi)); TetraIterator fi; for(fi = m.tetra.begin(); fi != m.tetra.end(); ++fi) { newVertices.push_back(InsertedVT( (*fi).V(0),&(*fi),0)); newVertices.push_back(InsertedVT( (*fi).V(1),&(*fi),1)); newVertices.push_back(InsertedVT( (*fi).V(2),&(*fi),2)); newVertices.push_back(InsertedVT( (*fi).V(3),&(*fi),3)); } sort(newVertices.begin(),newVertices.end()); typename std::vector< InsertedVT >::iterator curr,next; int pos = 0; curr = next = newVertices.begin(); while( next != newVertices.end()) { if((*curr)!=(*next)) pos++; (*next).t->V( (*next).z) = (VertexType *)pos; curr = next; next++; } typename std::vector<InsertedVT >::iterator newE = unique(newVertices.begin(),newVertices.end()); for(curr = newVertices.begin();curr!= newE;++curr) m.vert.push_back(*((*curr).v)); for(fi = m.tetra.begin(); fi != m.tetra.end(); ++fi) { (*fi).V(0) = &(m.vert[(int)(*fi).V(0)]); (*fi).V(1) = &(m.vert[(int)(*fi).V(1)]); (*fi).V(2) = &(m.vert[(int)(*fi).V(2)]); (*fi).V(3) = &(m.vert[(int)(*fi).V(3)]); } m.vn = m.vert.size(); m.tn = m.tetra.size(); } }; // end class /*@}*/ } // End namespace } // End namespace #endif