00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024 #ifndef SHUTIL_SHMESHIMPL_HPP
00025 #define SHUTIL_SHMESHIMPL_HPP
00026
00027 #include <iostream>
00028 #include <string>
00029 #include <map>
00030 #include "ShError.hpp"
00031 #include "ShException.hpp"
00032 #include "ShDebug.hpp"
00033 #include "ShMesh.hpp"
00034
00035 namespace ShUtil {
00036
00038 template<typename M>
00039 ShMeshVertex<M>::ShMeshVertex()
00040 : edge(0) {}
00041
00042 template<typename M>
00043 ShMeshVertex<M>::ShMeshVertex(const ShMeshVertex<M> &other)
00044 : edge(0) {}
00045
00046 template<typename M>
00047 ShMeshFace<M>::ShMeshFace()
00048 : edge(0) {}
00049
00050 template<typename M>
00051 ShMeshFace<M>::ShMeshFace(const ShMeshFace<M> &other)
00052 : edge(0) {}
00053
00055 template<typename M>
00056 ShMeshEdge<M>::ShMeshEdge()
00057 : start(0), end(0), face(0), sym(0), next(0), prev(0) {}
00058
00059 template<typename M>
00060 ShMeshEdge<M>::ShMeshEdge(const ShMeshEdge<M> &other)
00061 : start(0), end(0), face(0), sym(0), next(0), prev(0) {}
00062
00063 template<typename M>
00064 void ShMeshEdge<M>::setLinks(Vertex *s, Vertex *e, Face *f,
00065 Edge *next, Edge *prev, Edge *sym) {
00066
00067
00068 if(start || end) {
00069 SH_DEBUG_WARN("Changing start/end vertex of an edge. "
00070 << "This is probably not a good idea.");
00071 }
00072
00073 start = s;
00074 end = e;
00075 face = f;
00076 setNext(next);
00077 setPrev(prev);
00078 setSym(sym);
00079 }
00080
00081 template<typename M>
00082 void ShMeshEdge<M>::setNext(Edge *n) {
00083 if( next ) next->prev = 0;
00084 next = n;
00085 if( next ) next->prev = reinterpret_cast<Edge*>(this);
00086 }
00087
00088 template<typename M>
00089 void ShMeshEdge<M>::setPrev(Edge *p) {
00090 if( prev ) prev->next = 0;
00091 prev = p;
00092 if( prev ) prev->next = reinterpret_cast<Edge*>(this);
00093 }
00094
00095 template<typename M>
00096 void ShMeshEdge<M>::setSym(Edge *e) {
00097 if( sym ) sym->sym = 0;
00098 sym = e;
00099 if( sym ) sym->sym = reinterpret_cast<Edge*>(this);
00100 }
00101
00102
00103 template<typename M>
00104 ShMesh<M>::ShMesh() {}
00105
00106 template<typename M>
00107 ShMesh<M>::ShMesh(const ShMesh<M> &other) {
00108 *this = other;
00109 }
00110
00111 template<typename M>
00112 ShMesh<M>::~ShMesh() {
00113 clear();
00114 }
00115
00116 template<typename M>
00117 ShMesh<M>& ShMesh<M>::operator=(const ShMesh<M> &other) {
00118
00119
00120 VertexMap vmap;
00121 EdgeMap emap;
00122 FaceMap fmap;
00123
00124 SH_DEBUG_WARN("Assignment");
00125 clear();
00126
00127
00128 vmap[0] = 0;
00129 emap[0] = 0;
00130 fmap[0] = 0;
00131
00132
00133 for(typename EdgeSet::const_iterator J = other.edges.begin(); J != other.edges.end(); ++J) {
00134 Edge* newedge = new Edge(**J);
00135 edges.insert(newedge);
00136 emap[*J] = newedge;
00137 }
00138
00139 for(typename VertexSet::const_iterator I = other.verts.begin(); I != other.verts.end(); ++I) {
00140 Vertex* newvert = new Vertex(**I);
00141 verts.insert(newvert);
00142 vmap[*I] = newvert;
00143 newvert->edge = emap[(*I)->edge];
00144 }
00145
00146 for(typename FaceSet::const_iterator K = other.faces.begin(); K != other.faces.end(); ++K) {
00147 Face* newface = new Face(**K);
00148 faces.insert(newface);
00149 fmap[*K] = newface;
00150 newface->edge = emap[(*K)->edge];
00151 }
00152
00153 for(typename EdgeSet::const_iterator J = other.edges.begin(); J != other.edges.end(); ++J) {
00154 Edge *e = emap[*J];
00155 e->start = vmap[(*J)->start];
00156 e->end = vmap[(*J)->end];
00157 e->face = fmap[(*J)->face];
00158 e->sym = emap[(*J)->sym];
00159 e->prev = emap[(*J)->prev];
00160 e->next = emap[(*J)->next];
00161 m_incidences.insert(Incidence(e->start, e));
00162 }
00163
00164 return *this;
00165 }
00166
00167 template<typename M>
00168 void ShMesh<M>::clear() {
00169 for(typename VertexSet::iterator I = verts.begin(); I != verts.end(); ++I) {
00170 delete (*I);
00171 }
00172 verts.clear();
00173
00174 for(typename FaceSet::iterator K = faces.begin(); K != faces.end(); ++K) {
00175 delete (*K);
00176 }
00177 faces.clear();
00178
00179 for(typename EdgeSet::iterator J = edges.begin(); J != edges.end(); ++J) {
00180 delete (*J);
00181 }
00182 edges.clear();
00183
00184 m_incidences.clear();
00185 }
00186
00187 template<typename M>
00188 typename ShMesh<M>::Face*
00189 ShMesh<M>::addFace(const typename ShMesh<M>::VertexList &vl) {
00190 verts.insert(vl.begin(), vl.end());
00191
00192 if( vl.size() < 1 ) {
00193 SH::shError(SH::ShException("ShMesh::addFace can only handle faces with >= 1 vertices"));
00194 }
00195 Face *newf = new Face();
00196 faces.insert(newf);
00197
00198 Edge *newe = 0, *olde = 0;
00199 Vertex *first = vl.front();
00200 for(typename VertexList::const_iterator I = vl.begin(); I != vl.end();) {
00201 Vertex *start = *(I++);
00202 Vertex *end = (I == vl.end() ? first : *I);
00203
00204 SH_DEBUG_ASSERT(start);
00205
00206 newe = new Edge();
00207 newe->setLinks(start, end, newf, 0, olde, 0);
00208 olde = newe;
00209
00210 if( !newf->edge ) newf->edge = newe;
00211 insertHalfEdge(newe);
00212 }
00213 newf->edge->setPrev(newe);
00214 return newf;
00215 }
00216
00217
00218 template<typename M>
00219 void ShMesh<M>::removeFace(Face *f) {
00220 Edge *olde, *e;
00221 e = f->edge;
00222
00223
00224
00225
00226 do {
00227 olde = e;
00228 e = e->next;
00229 removeHalfEdge(e);
00230 } while( e != f->edge );
00231 faces.erase(f);
00232 delete f;
00233 }
00234
00235 template<typename M>
00236 template<typename VertLess>
00237 void ShMesh<M>::mergeVertices() {
00238 typedef std::map<Vertex*, Vertex*, VertLess> MergedVertMap;
00239 MergedVertMap mvmap;
00240
00241
00242 for(typename VertexSet::iterator I = verts.begin(); I != verts.end(); ++I) {
00243 if( mvmap.count(*I) == 0 ) mvmap[*I] = *I;
00244 }
00245
00246 for(typename EdgeSet::iterator J = edges.begin(); J != edges.end(); ++J) {
00247 (*J)->start = mvmap[(*J)->start];
00248 (*J)->end = mvmap[(*J)->end];
00249 }
00250
00251
00252
00253
00254
00255 for(typename VertexSet::iterator I = verts.begin(); I != verts.end();) {
00256 if( mvmap[*I] != *I ) {
00257 typename VertexSet::iterator deadI = I;
00258 ++I;
00259 Vertex *deadVert = *deadI;
00260 verts.erase(deadI);
00261
00262
00263 IncidenceRange ir = m_incidences.equal_range(deadVert);
00264 for(IncidenceIterator K = ir.first; K != ir.second; ++K) {
00265 m_incidences.insert(Incidence(mvmap[K->first], K->second));
00266 }
00267 m_incidences.erase(ir.first, ir.second);
00268
00269 delete deadVert;
00270 } else {
00271 ++I;;
00272 }
00273 }
00274 }
00275
00276 template<typename M>
00277 void ShMesh<M>::mergeEdges() {
00278 typedef std::map<Vertex*, std::map<Vertex*, Edge*> > EdgeMatchMap;
00279
00280 EdgeMatchMap edgeMatch;
00281
00282 for(typename EdgeSet::iterator J = edges.begin(); J != edges.end(); ++J) {
00283 Edge *e = (*J);
00284 Edge *match = edgeMatch[e->end][e->start];
00285
00286 if(match) match->setSym(e);
00287
00288 if( edgeMatch[e->start][e->end] != 0 ) {
00289 SH_DEBUG_WARN("Duplicate edge found in mesh");
00290 }
00291 edgeMatch[e->start][e->end] = e;
00292 }
00293 }
00294
00295 template<typename M>
00296 bool ShMesh<M>::earTriangulate() {
00297 bool changed = false;
00298 for(typename FaceSet::iterator I = faces.begin(); I != faces.end(); ++I) {
00299 Edge *e = (*I)->edge;
00300
00301 if( e->next->next->next == e ) continue;
00302
00303 changed = true;
00304 if( e->next == e || e->next->next == e ) {
00305 removeFace(*(I++));
00306 continue;
00307 }
00308
00309
00310 Face *lastface = *I;
00311 Edge *e0 = e;
00312 Edge *en = e0->prev;
00313 for(e = e->next->next; e != en; e = e->next) {
00314 Face *newf = new Face();
00315 newf->edge = e;
00316
00317
00318 Edge *ee0 = new Edge(*e);
00319 ee0->setLinks(e->start, e0->start, lastface, e->prev->prev, e->prev, 0);
00320
00321 Edge *e0e = new Edge(*e0);
00322 e0e->setLinks(e0->start, e->start, newf, e, en, 0);
00323
00324 ee0->setSym(e0e);
00325
00326 insertHalfEdge(ee0);
00327 insertHalfEdge(e0e);
00328 faces.insert(newf);
00329
00330 lastface = newf;
00331 }
00332 e->face = lastface;
00333 }
00334 return changed;
00335 }
00336
00337 template<typename M>
00338 void ShMesh<M>::removeHalfEdge(Edge *e) {
00339 edges.erase(e);
00340 e->setNext(0);
00341 e->setPrev(0);
00342 e->setSym(0);
00343
00344
00345 IncidenceRange ir = m_incidences.equal_range(e->start);
00346 for(IncidenceIterator I = ir.first; I != ir.second; ++I) {
00347 if(I->second == e) {
00348 m_incidences.erase(I);
00349 break;
00350 }
00351 }
00352 if(e->start->edge == e) {
00353 if(m_incidences.count(e->start) > 0) {
00354 e->start->edge = m_incidences.find(e->start)->second;
00355 } else {
00356 e->start->edge = 0;
00357 }
00358 }
00359 delete e;
00360 }
00361
00362 template<typename M>
00363 void ShMesh<M>::insertHalfEdge(Edge *e) {
00364 edges.insert(e);
00365 SH_DEBUG_ASSERT(e->start);
00366 m_incidences.insert(Incidence(e->start, e));
00367 }
00368
00369 }
00370
00371 #endif