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