00001 #ifndef MLS_ADVANCE_H
00002 #define MLS_ADVANCE_H
00003
00004 #include <iostream>
00005 #include <list>
00006 #include <vcg/complex/algorithms/update/topology.h>
00007 #include <vcg/complex/algorithms/update/flag.h>
00008
00009 namespace vcg {
00010 namespace tri {
00011
00012
00013
00014
00015
00016
00017 class FrontEdge {
00018 public:
00019 int v0, v1, v2;
00020
00021 bool active;
00022
00023
00024 std::list<FrontEdge>::iterator next;
00025 std::list<FrontEdge>::iterator previous;
00026
00027 FrontEdge() {}
00028 FrontEdge(int _v0, int _v1, int _v2):
00029 v0(_v0), v1(_v1), v2(_v2), active(true) {
00030 assert(v0 != v1 && v1 != v2 && v0 != v2);
00031 }
00032
00033 bool operator==(const FrontEdge& f) const
00034 {
00035 return ((v0 == f.v0) && (v1 == f.v1) && (v2 == f.v2) );
00036 }
00037 };
00038
00039 template <class MESH> class AdvancingFront {
00040 public:
00041
00042 typedef typename MESH::VertexType VertexType;
00043 typedef typename MESH::FaceType FaceType;
00044 typedef typename MESH::FaceIterator FaceIterator;
00045 typedef typename MESH::ScalarType ScalarType;
00046 typedef typename MESH::VertexType::CoordType Point3x;
00047
00048
00049
00050
00051
00052
00053
00054
00055 std::list<FrontEdge> front;
00056 std::list<FrontEdge> deads;
00057 std::vector<int> nb;
00058
00059
00060
00061 public:
00062
00063 MESH &mesh;
00064
00065 AdvancingFront(MESH &_mesh): mesh(_mesh) {
00066
00067
00068 UpdateFlags<MESH>::FaceBorderFromNone(mesh);
00069 UpdateFlags<MESH>::VertexBorderFromFaceBorder(mesh);
00070
00071 nb.clear();
00072 nb.resize(mesh.vert.size(), 0);
00073
00074 CreateLoops();
00075 }
00076 virtual ~AdvancingFront() {}
00077
00078 void BuildMesh(CallBackPos call = NULL, int interval = 512)
00079 {
00080 float finalfacesext = mesh.vert.size() * 2.0f;
00081 if(call) call(0, "Advancing front");
00082 while(1) {
00083
00084 for(int i = 0; i < interval; i++) {
00085 if(!front.size() && !SeedFace()) return;
00086 AddFace();
00087 if(call)
00088 {
00089 float rap = float(mesh.face.size()) / finalfacesext;
00090 int perc = (int) (100.0f * rap);
00091 (*call)(perc,"Adding Faces");
00092 }
00093 }
00094 }
00095 }
00096
00097 protected:
00098
00099 enum ListID {FRONT,DEADS};
00100 typedef std::pair< ListID,std::list<FrontEdge>::iterator > ResultIterator;
00101 virtual bool Seed(int &v0, int &v1, int &v2) = 0;
00102
00103
00104 virtual int Place(FrontEdge &e, ResultIterator &touch) = 0;
00105
00106
00107 void CreateLoops()
00108 {
00109 for(size_t i = 0; i < mesh.face.size(); i++)
00110 {
00111 FaceType &f = mesh.face[i];
00112 if(f.IsD()) continue;
00113
00114 for(int k = 0; k < 3; k++) {
00115 if(f.IsB(k)) {
00116 addNewEdge(FrontEdge(tri::Index(mesh,f.V0(k)),tri::Index(mesh,f.V1(k)),tri::Index(mesh,f.V2(k))) );
00117 nb[tri::Index(mesh,f.V0(k))]++;
00118 }
00119 }
00120 }
00121
00122 for(std::list<FrontEdge>::iterator s = front.begin(); s != front.end(); s++) {
00123 (*s).previous = front.end();
00124 (*s).next = front.end();
00125 }
00126
00127 for(std::list<FrontEdge>::iterator s = front.begin(); s != front.end(); s++) {
00128 for(std::list<FrontEdge>::iterator j = front.begin(); j != front.end(); j++) {
00129 if(s == j) continue;
00130 if((*s).v1 != (*j).v0) continue;
00131 if((*j).previous != front.end()) continue;
00132 (*s).next = j;
00133 (*j).previous = s;
00134 break;
00135 }
00136 }
00137 for(std::list<FrontEdge>::iterator s = front.begin(); s != front.end(); s++) {
00138 assert((*s).next != front.end());
00139 assert((*s).previous != front.end());
00140 }
00141 }
00142
00143 bool SeedFace() {
00144 int v[3];
00145 bool success = Seed(v[0], v[1], v[2]);
00146 if(!success) return false;
00147
00148 nb.resize(mesh.vert.size(), 0);
00149
00150
00151 std::list<FrontEdge>::iterator e = front.end();
00152 std::list<FrontEdge>::iterator last = e;
00153 std::list<FrontEdge>::iterator first;
00154
00155 for(int i = 0; i < 3; i++) {
00156 int v0 = v[i];
00157 int v1 = v[((i+1)%3)];
00158 int v2 = v[((i+2)%3)];
00159
00160 mesh.vert[v0].SetB();
00161 nb[v[i]]++;
00162
00163 e = front.insert(front.begin(), FrontEdge(v0, v1, v2));
00164 if(i != 0) {
00165 (*last).next = e;
00166 (*e).previous = last;
00167 } else
00168 first = e;
00169
00170 last = e;
00171 }
00172
00173 (*last).next = first;
00174 (*first).previous = last;
00175
00176 AddFace(v[0], v[1], v[2]);
00177 return true;
00178 }
00179
00180 public:
00181 bool AddFace() {
00182 if(!front.size()) return false;
00183
00184 std::list<FrontEdge>::iterator ei = front.begin();
00185 FrontEdge ¤t = *ei;
00186 FrontEdge &previous = *current.previous;
00187 FrontEdge &next = *current.next;
00188
00189 int v0 = current.v0, v1 = current.v1;
00190 assert(nb[v0] < 10 && nb[v1] < 10);
00191
00192 ResultIterator touch;
00193 touch.first = FRONT;
00194 touch.second = front.end();
00195 int v2 = Place(current, touch);
00196
00197 if(v2 == -1) {
00198 KillEdge(ei);
00199 return false;
00200 }
00201
00202 assert(v2 != v0 && v2 != v1);
00203
00204 if ( ( (touch.first == FRONT) && (touch.second != front.end()) ) ||
00205 ( (touch.first == DEADS) && (touch.second != deads.end()) ) )
00206
00207 {
00208
00209
00210
00211 if(v2 == previous.v0) {
00212 if(!CheckEdge(v2, v1)) {
00213 KillEdge(ei);
00214 return false;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 Detach(v0);
00226
00227 std::list<FrontEdge>::iterator up = addNewEdge(FrontEdge(v2, v1, v0));
00228 MoveFront(up);
00229 (*up).previous = previous.previous;
00230 (*up).next = current.next;
00231 (*previous.previous).next = up;
00232 next.previous = up;
00233 Erase(current.previous);
00234 Erase(ei);
00235 Glue(up);
00236
00237
00238 } else if(v2 == next.v1) {
00239 if(!CheckEdge(v0, v2)) {
00240 KillEdge(ei);
00241 return false;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 Detach(v1);
00253 std::list<FrontEdge>::iterator up = addNewEdge(FrontEdge(v0, v2, v1));
00254 MoveFront(up);
00255 (*up).previous = current.previous;
00256 (*up).next = (*current.next).next;
00257 previous.next = up;
00258 (*next.next).previous = up;
00259 Erase(current.next);
00260 Erase(ei);
00261 Glue(up);
00262 } else {
00263 if(!CheckEdge(v0, v2) || !CheckEdge(v2, v1)) {
00264 KillEdge(ei);
00265 return false;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 std::list<FrontEdge>::iterator left = touch.second;
00280 std::list<FrontEdge>::iterator right = (*touch.second).previous;
00281
00282
00283 if(v1 == (*right).v0 || v0 == (*left).v1) {
00284 KillEdge(ei);
00285 return false;
00286 }
00287
00288 nb[v2]++;
00289
00290 std::list<FrontEdge>::iterator down = addNewEdge(FrontEdge(v2, v1, v0));
00291 std::list<FrontEdge>::iterator up = addNewEdge(FrontEdge(v0, v2, v1));
00292
00293 (*right).next = down;
00294 (*down).previous = right;
00295
00296 (*down).next = current.next;
00297 next.previous = down;
00298
00299 (*left).previous = up;
00300 (*up).next = left;
00301
00302 (*up).previous = current.previous;
00303 previous.next = up;
00304 Erase(ei);
00305 }
00306
00307
00308 }
00309 else if (((touch.first == FRONT) && (touch.second == front.end())) ||
00310 ((touch.first == DEADS) && (touch.second == deads.end())) )
00311 {
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 assert(!mesh.vert[v2].IsB());
00324 nb[v2]++;
00325 mesh.vert[v2].SetB();
00326
00327 std::list<FrontEdge>::iterator down = addNewEdge(FrontEdge(v2, v1, v0));
00328 std::list<FrontEdge>::iterator up = addNewEdge(FrontEdge(v0, v2, v1));
00329
00330 (*down).previous = up;
00331 (*up).next = down;
00332 (*down).next = current.next;
00333 next.previous = down;
00334 (*up).previous = current.previous;
00335 previous.next = up;
00336 Erase(ei);
00337 }
00338
00339 AddFace(v0, v2, v1);
00340 return false;
00341 }
00342
00343 protected:
00344 void AddFace(int v0, int v1, int v2) {
00345 FaceIterator fi = vcg::tri::Allocator<MESH>::AddFace(mesh,v0,v1,v2);
00346 fi->N() = TriangleNormal(*fi).Normalize();
00347 if(tri::HasVFAdjacency(mesh))
00348 {
00349 for(int j=0;j<3;++j)
00350 {
00351 (*fi).VFp(j) = (*fi).V(j)->VFp();
00352 (*fi).VFi(j) = (*fi).V(j)->VFi();
00353 (*fi).V(j)->VFp() = &(*fi);
00354 (*fi).V(j)->VFi() = j;
00355 }
00356 }
00357 }
00358
00359 void AddVertex(VertexType &vertex) {
00360 VertexType *oldstart = NULL;
00361 if(mesh.vert.size()) oldstart = &*mesh.vert.begin();
00362 mesh.vert.push_back(vertex);
00363 mesh.vn++;
00364 VertexType *newstart = &*mesh.vert.begin();
00365 if(oldstart && oldstart != newstart) {
00366 for(int i = 0; i < mesh.face.size(); i++) {
00367 FaceType &face = mesh.face[i];
00368 for(int k = 0; k < 3; k++)
00369 face.V(k) = newstart + (face.V(k) - oldstart);
00370 }
00371 }
00372 nb.push_back(0);
00373 }
00374
00375
00376
00377
00378
00379
00380 bool CheckEdge(int v0, int v1) {
00381 int tot = 0;
00382 VertexType *vv0 = &(mesh.vert[v0]);
00383 VertexType *vv1 = &(mesh.vert[v1]);
00384 if(tri::HasVFAdjacency(mesh))
00385 {
00386 face::VFIterator<FaceType> vfi(vv0);
00387 for (;!vfi.End();++vfi)
00388 {
00389 FaceType *f = vfi.F();
00390 for(int k = 0; k < 3; k++) {
00391 if(vv0 == f->V0(k) && vv1 == f->V1(k))
00392 return false;
00393 else if(vv1 == f->V0(k) && vv0 == f->V1(k)) ++tot;
00394 }
00395 }
00396 return true;
00397 }
00398 for(int i = 0; i < (int)mesh.face.size(); i++) {
00399 FaceType &f = mesh.face[i];
00400 for(int k = 0; k < 3; k++) {
00401 if(vv0 == f.V0(k) && vv1 == f.V1(k))
00402 return false;
00403 else if(vv1 == f.V0(k) && vv0 == f.V1(k)) ++tot;
00404 }
00405 if(tot >= 2) {
00406 return false;
00407 }
00408 }
00409 return true;
00410 }
00411
00412
00413
00414 std::list<FrontEdge>::iterator addNewEdge(FrontEdge e) {
00415 return front.insert(front.end(), e);
00416 }
00417
00418
00419 void KillEdge(std::list<FrontEdge>::iterator e)
00420 {
00421 if (e->active)
00422 {
00423 (*e).active = false;
00424
00425 FrontEdge tmp = *e;
00426 deads.splice(deads.end(), front, e);
00427 std::list<FrontEdge>::iterator newe = std::find(deads.begin(),deads.end(),tmp);
00428 tmp.previous->next = newe;
00429 tmp.next->previous = newe;
00430 }
00431 }
00432
00433 void Erase(std::list<FrontEdge>::iterator e) {
00434 if((*e).active) front.erase(e);
00435 else deads.erase(e);
00436 }
00437
00438
00439 void MoveBack(std::list<FrontEdge>::iterator e) {
00440 front.splice(front.end(), front, e);
00441 }
00442
00443 void MoveFront(std::list<FrontEdge>::iterator e) {
00444 front.splice(front.begin(), front, e);
00445 }
00446
00447
00448 bool Glue(std::list<FrontEdge>::iterator e) {
00449 return Glue((*e).previous, e) || Glue(e, (*e).next);
00450 }
00451
00452
00453 bool Glue(std::list<FrontEdge>::iterator a, std::list<FrontEdge>::iterator b) {
00454 if((*a).v0 != (*b).v1) return false;
00455
00456 std::list<FrontEdge>::iterator previous = (*a).previous;
00457 std::list<FrontEdge>::iterator next = (*b).next;
00458 (*previous).next = next;
00459 (*next).previous = previous;
00460 Detach((*a).v1);
00461 Detach((*a).v0);
00462 Erase(a);
00463 Erase(b);
00464 return true;
00465 }
00466
00467 void Detach(int v) {
00468 assert(nb[v] > 0);
00469 if(--nb[v] == 0) {
00470 mesh.vert[v].ClearB();
00471 }
00472 }
00473 };
00474
00475 template <class MESH> class AdvancingTest: public AdvancingFront<MESH> {
00476 public:
00477 typedef typename MESH::VertexType VertexType;
00478 typedef typename MESH::VertexIterator VertexIterator;
00479 typedef typename MESH::FaceType FaceType;
00480 typedef typename MESH::FaceIterator FaceIterator;
00481
00482 typedef typename MESH::ScalarType ScalarType;
00483 typedef typename MESH::VertexType::CoordType Point3x;
00484
00485 AdvancingTest(MESH &_mesh): AdvancingFront<MESH>(_mesh) {}
00486
00487 bool Seed(int &v0, int &v1, int &v2) {
00488 VertexType v[3];
00489 v[0].P() = Point3x(0, 0, 0);
00490 v[1].P() = Point3x(1, 0, 0);
00491 v[2].P() = Point3x(0, 1, 0);
00492 v[0].ClearFlags();
00493 v[1].ClearFlags();
00494 v[2].ClearFlags();
00495
00496 v0 = this->mesh.vert.size();
00497 AddVertex(v[0]);
00498 v1 = this->mesh.vert.size();
00499 AddVertex(v[1]);
00500 v2 = this->mesh.vert.size();
00501 AddVertex(v[2]);
00502 return true;
00503 }
00504
00505 int Place(FrontEdge &e, typename AdvancingFront<MESH>::ResultIterator &touch)
00506 {
00507 Point3f p[3];
00508 p[0] = this->mesh.vert[e.v0].P();
00509 p[1] = this->mesh.vert[e.v1].P();
00510 p[2] = this->mesh.vert[e.v2].P();
00511 Point3f point = p[0] + p[1] - p[2];
00512
00513 int vn = this->mesh.vert.size();
00514 for(int i = 0; i < this->mesh.vert.size(); i++)
00515 {
00516 if((this->mesh.vert[i].P() - point).Norm() < 0.1)
00517 {
00518 vn = i;
00519
00520 assert(this->mesh.vert[i].IsB());
00521 for(std::list<FrontEdge>::iterator k = this->front.begin(); k != this->front.end(); k++)
00522 if((*k).v0 == i)
00523 {
00524 touch.first = AdvancingFront<MESH>::FRONT;
00525 touch.second = k;
00526 }
00527
00528 for(std::list<FrontEdge>::iterator k = this->deads.begin(); k != this->deads.end(); k++)
00529 if((*k).v0 == i)
00530 if((*k).v0 == i)
00531 {
00532 touch.first = AdvancingFront<MESH>::FRONT;
00533 touch.second = k;
00534 }
00535 break;
00536 }
00537 }
00538 if(vn == this->mesh.vert.size()) {
00539 VertexType v;
00540 v.P() = point;
00541 v.ClearFlags();
00542 AddVertex(v);
00543 }
00544 return vn;
00545 }
00546 };
00547
00548 }
00549 }
00550
00551 #endif