00001 #ifndef MLS_ADVANCE_H
00002 #define MLS_ADVANCE_H
00003
00004 #include <iostream>
00005 #include <list>
00006 #include <wrap/callback.h>
00007 #include <vcg/complex/trimesh/update/topology.h>
00008 #include <vcg/complex/trimesh/update/flag.h>
00009 #include <map>
00010
00011 namespace vcg {
00012 namespace tri {
00013
00014 class FrontEdge {
00015 public:
00016 int v0, v1, v2;
00017
00018 int face;
00019 bool active;
00020
00021
00022 std::list<FrontEdge>::iterator next;
00023 std::list<FrontEdge>::iterator previous;
00024
00025 FrontEdge() {}
00026 FrontEdge(int _v0, int _v1, int _v2, int _face):
00027 v0(_v0), v1(_v1), v2(_v2), face(_face), active(true) {
00028 assert(v0 != v1 && v1 != v2 && v0 != v2);
00029 }
00030
00031 const bool operator==(const FrontEdge& f) const
00032 {
00033 return ((v0 == f.v0) && (v1 == f.v1) && (v2 == f.v2) && (face == f.face));
00034 }
00035 };
00036
00037 template <class MESH> class AdvancingFront {
00038 public:
00039
00040 typedef typename MESH::VertexType VertexType;
00041 typedef typename MESH::FaceType FaceType;
00042 typedef typename MESH::ScalarType ScalarType;
00043 typedef typename MESH::VertexType::CoordType Point3x;
00044
00045
00046
00047
00048
00049
00050
00051
00052 std::list<FrontEdge> front;
00053 std::list<FrontEdge> deads;
00054 std::vector<int> nb;
00055
00056
00057
00058 public:
00059
00060 MESH &mesh;
00061
00062 AdvancingFront(MESH &_mesh): mesh(_mesh) {
00063
00064
00065 UpdateFlags<MESH>::FaceBorderFromNone(mesh);
00066 UpdateFlags<MESH>::VertexBorderFromFace(mesh);
00067
00068 nb.clear();
00069 nb.resize(mesh.vert.size(), 0);
00070
00071 CreateLoops();
00072 }
00073 virtual ~AdvancingFront() {}
00074 virtual ScalarType radi() { return 0; }
00075
00076 void BuildMesh(CallBackPos call = NULL, int interval = 512) {
00077 float finalfacesext = mesh.vert.size() * 2.0f;
00078 if(call) call(0, "Advancing front");
00079 while(1) {
00080
00081 for(int i = 0; i < interval; i++) {
00082 if(!front.size() && !SeedFace()) return;
00083 AddFace();
00084 if(call)
00085 {
00086 float rap = float(mesh.face.size()) / finalfacesext;
00087 int perc = (int) (100.0f * rap);
00088 (*call)(perc,"Adding Faces");
00089 }
00090 }
00091 }
00092 }
00093
00094 protected:
00095
00096 enum ListID {FRONT,DEADS};
00097 typedef std::pair< ListID,std::list<FrontEdge>::iterator > ResultIterator;
00098 virtual bool Seed(int &v0, int &v1, int &v2) = 0;
00099 virtual int Place(FrontEdge &e, ResultIterator &touch) = 0;
00100
00101 bool CheckFrontEdge(int v0, int v1) {
00102 int tot = 0;
00103
00104
00105
00106 int i = 0;
00107 if(i < 0) i = 0;
00108 for(; i < (int)mesh.face.size(); i++) {
00109 FaceType &f = mesh.face[i];
00110 for(int k = 0; k < 3; k++) {
00111 if(v1== (int)f.V(k) && v0 == (int)f.V((k+1)%3)) ++tot;
00112 else if(v0 == (int)f.V(k) && v1 == (int)f.V((k+1)%3)) {
00113 return false;
00114 }
00115 }
00116 if(tot >= 2) {
00117 return false;
00118 }
00119 }
00120 return true;
00121 }
00122
00123
00124 void CreateLoops() {
00125 VertexType *start = &*mesh.vert.begin();
00126 for(int i = 0; i < (int)mesh.face.size(); i++) {
00127 FaceType &f = mesh.face[i];
00128 if(f.IsD()) continue;
00129
00130 for(int k = 0; k < 3; k++) {
00131 if(f.IsB(k)) {
00132 NewEdge(FrontEdge(f.V0(k) - start, f.V1(k) - start, f.V2(k) - start, i));
00133 nb[f.V0(k)-start]++;
00134 }
00135 }
00136 }
00137
00138 for(std::list<FrontEdge>::iterator s = front.begin(); s != front.end(); s++) {
00139 (*s).previous = front.end();
00140 (*s).next = front.end();
00141 }
00142
00143 for(std::list<FrontEdge>::iterator s = front.begin(); s != front.end(); s++) {
00144 for(std::list<FrontEdge>::iterator j = front.begin(); j != front.end(); j++) {
00145 if(s == j) continue;
00146 if((*s).v1 != (*j).v0) continue;
00147 if((*j).previous != front.end()) continue;
00148 (*s).next = j;
00149 (*j).previous = s;
00150 break;
00151 }
00152 }
00153 for(std::list<FrontEdge>::iterator s = front.begin(); s != front.end(); s++) {
00154 assert((*s).next != front.end());
00155 assert((*s).previous != front.end());
00156 }
00157 }
00158
00159 bool SeedFace() {
00160 int v[3];
00161 bool success = Seed(v[0], v[1], v[2]);
00162 if(!success) return false;
00163
00164 nb.resize(mesh.vert.size(), 0);
00165
00166
00167 std::list<FrontEdge>::iterator e = front.end();
00168 std::list<FrontEdge>::iterator last = e;
00169 std::list<FrontEdge>::iterator first;
00170
00171 for(int i = 0; i < 3; i++) {
00172 int v0 = v[i];
00173 int v1 = v[((i+1)%3)];
00174 int v2 = v[((i+2)%3)];
00175
00176 mesh.vert[v0].SetB();
00177 nb[v[i]]++;
00178
00179 e = front.insert(front.begin(), FrontEdge(v0, v1, v2, mesh.face.size()));
00180 if(i != 0) {
00181 (*last).next = e;
00182 (*e).previous = last;
00183 } else
00184 first = e;
00185
00186 last = e;
00187 }
00188
00189 (*last).next = first;
00190 (*first).previous = last;
00191
00192 AddFace(v[0], v[1], v[2]);
00193 return true;
00194 }
00195
00196 public:
00197 bool AddFace() {
00198 if(!front.size()) return false;
00199
00200 std::list<FrontEdge>::iterator ei = front.begin();
00201 FrontEdge ¤t = *ei;
00202 FrontEdge &previous = *current.previous;
00203 FrontEdge &next = *current.next;
00204
00205 int v0 = current.v0, v1 = current.v1;
00206 assert(nb[v0] < 10 && nb[v1] < 10);
00207
00208 ResultIterator touch;
00209 touch.first = FRONT;
00210 touch.second = front.end();
00211 int v2 = Place(current, touch);
00212
00213 if(v2 == -1) {
00214 KillEdge(ei);
00215 return false;
00216 }
00217
00218 assert(v2 != v0 && v2 != v1);
00219
00220 if ((touch.first == FRONT) && (touch.second != front.end()) ||
00221 (touch.first == DEADS) && (touch.second != deads.end()))
00222
00223 {
00224
00225
00226
00227 if(v2 == previous.v0) {
00228 if(!CheckEdge(v2, v1)) {
00229 KillEdge(ei);
00230 return false;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 Detach(v0);
00242
00243 std::list<FrontEdge>::iterator up = NewEdge(FrontEdge(v2, v1, v0, mesh.face.size()));
00244 MoveFront(up);
00245 (*up).previous = previous.previous;
00246 (*up).next = current.next;
00247 (*previous.previous).next = up;
00248 next.previous = up;
00249 Erase(current.previous);
00250 Erase(ei);
00251 Glue(up);
00252
00253
00254 } else if(v2 == next.v1) {
00255 if(!CheckEdge(v0, v2)) {
00256 KillEdge(ei);
00257 return false;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 Detach(v1);
00269 std::list<FrontEdge>::iterator up = NewEdge(FrontEdge(v0, v2, v1, mesh.face.size()));
00270 MoveFront(up);
00271 (*up).previous = current.previous;
00272 (*up).next = (*current.next).next;
00273 previous.next = up;
00274 (*next.next).previous = up;
00275 Erase(current.next);
00276 Erase(ei);
00277 Glue(up);
00278 } else {
00279 if(!CheckEdge(v0, v2) || !CheckEdge(v2, v1)) {
00280 KillEdge(ei);
00281 return false;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 std::list<FrontEdge>::iterator left = touch.second;
00296 std::list<FrontEdge>::iterator right = (*touch.second).previous;
00297
00298
00299 if(v1 == (*right).v0 || v0 == (*left).v1) {
00300 KillEdge(ei);
00301 return false;
00302 }
00303
00304 nb[v2]++;
00305
00306 std::list<FrontEdge>::iterator down = NewEdge(FrontEdge(v2, v1, v0, mesh.face.size()));
00307 std::list<FrontEdge>::iterator up = NewEdge(FrontEdge(v0, v2, v1, mesh.face.size()));
00308
00309 (*right).next = down;
00310 (*down).previous = right;
00311
00312 (*down).next = current.next;
00313 next.previous = down;
00314
00315 (*left).previous = up;
00316 (*up).next = left;
00317
00318 (*up).previous = current.previous;
00319 previous.next = up;
00320 Erase(ei);
00321 }
00322
00323
00324 }
00325 else if ((touch.first == FRONT) && (touch.second == front.end()) ||
00326 (touch.first == DEADS) && (touch.second == deads.end()))
00327 {
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 assert(!mesh.vert[v2].IsB());
00340 nb[v2]++;
00341 mesh.vert[v2].SetB();
00342
00343 std::list<FrontEdge>::iterator down = NewEdge(FrontEdge(v2, v1, v0, mesh.face.size()));
00344 std::list<FrontEdge>::iterator up = NewEdge(FrontEdge(v0, v2, v1, mesh.face.size()));
00345
00346 (*down).previous = up;
00347 (*up).next = down;
00348 (*down).next = current.next;
00349 next.previous = down;
00350 (*up).previous = current.previous;
00351 previous.next = up;
00352 Erase(ei);
00353 }
00354
00355 AddFace(v0, v2, v1);
00356 return false;
00357 }
00358
00359 protected:
00360 void AddFace(int v0, int v1, int v2) {
00361 assert(v0 < (int)mesh.vert.size() && v1 < (int)mesh.vert.size() && v2 < (int)mesh.vert.size());
00362 FaceType face;
00363 face.V(0) = &mesh.vert[v0];
00364 face.V(1) = &mesh.vert[v1];
00365 face.V(2) = &mesh.vert[v2];
00366 ComputeNormalizedNormal(face);
00367 mesh.face.push_back(face);
00368 mesh.fn++;
00369 }
00370
00371 void AddVertex(VertexType &vertex) {
00372 VertexType *oldstart = NULL;
00373 if(mesh.vert.size()) oldstart = &*mesh.vert.begin();
00374 mesh.vert.push_back(vertex);
00375 mesh.vn++;
00376 VertexType *newstart = &*mesh.vert.begin();
00377 if(oldstart && oldstart != newstart) {
00378 for(int i = 0; i < mesh.face.size(); i++) {
00379 FaceType &face = mesh.face[i];
00380 for(int k = 0; k < 3; k++)
00381 face.V(k) = newstart + (face.V(k) - oldstart);
00382 }
00383 }
00384 nb.push_back(0);
00385 }
00386
00387
00388 bool CheckEdge(int v0, int v1) {
00389 int tot = 0;
00390
00391
00392
00393
00394 VertexType *vv0 = &(mesh.vert[v0]);
00395 VertexType *vv1 = &(mesh.vert[v1]);
00396
00397 for(int i = 0; i < (int)mesh.face.size(); i++) {
00398 FaceType &f = mesh.face[i];
00399 for(int k = 0; k < 3; k++) {
00400 if(vv0 == f.V0(k) && vv1 == f.V1(k))
00401 return false;
00402 else if(vv1 == f.V0(k) && vv0 == f.V1(k)) ++tot;
00403 }
00404 if(tot >= 2) {
00405 return false;
00406 }
00407 }
00408 return true;
00409 }
00410
00411
00412
00413 std::list<FrontEdge>::iterator NewEdge(FrontEdge e) {
00414 return front.insert(front.end(), e);
00415 }
00416
00417
00418 void KillEdge(std::list<FrontEdge>::iterator e)
00419 {
00420 if (e->active)
00421 {
00422 (*e).active = false;
00423
00424 FrontEdge tmp = *e;
00425 deads.splice(deads.end(), front, e);
00426 std::list<FrontEdge>::iterator newe = std::find(deads.begin(),deads.end(),tmp);
00427 tmp.previous->next = newe;
00428 tmp.next->previous = newe;
00429 }
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